Download - 2_Divide y Venceras
-
ANLISIS DE
ALGORITMOS Escuela Superior de Cmputo
-
Contenido
Introduccin
Divide y vencers
Observaciones sobre Divide y Vencers
Complejidad de divide y vencers
Ejemplo: Bsqueda del mximo y del
mnimo
Ejercicios: Algoritmos de ordenamiento
(Mergesort y Quicksort)
-
Introduccin En la cultura popular, divide y vencers hace referencia a
un refrn que implica resolver un problema difcil, dividindolo en partes ms simples tantas veces como sea necesario, hasta que la resolucin de las partes se torna obvia. La solucin del problema principal se construye con las soluciones encontradas.
En las ciencias de la computacin, el trmino divide y vencers hace referencia a uno de los ms importantes paradigmas de diseo algortmico.
-
El paradigma divide y vencers, est basado en buscar la resolucin recursiva de un problema dividindolo en dos o ms subproblemas de igual tipo o similar (Sin que se solapen). El proceso contina hasta que stos llegan a ser lo suficientemente sencillos como para que se resuelvan directamente. Al final, las soluciones a cada uno de los subproblemas se combinan para dar una solucin al problema original.
Ordenamiento por mezcla
-
Dividir y vencer es la base de varios algoritmos eficientes para casi cualquier tipo de problema como, por ejemplo, algoritmos de ordenamiento (mergesort, quicksort, entre otros), multiplicar nmeros grandes (Karatsuba), anlisis sintcticos (top-down), la transformada discreta de Fourier, multiplicacin rpida de matrices (Strassen), etc.
Analizar y disear algoritmos de DyV son tareas que lleva tiempo dominar. Al igual que en la induccin, a veces es necesario sustituir el problema original por uno ms complejo para conseguir realizar la recursin, y no hay un mtodo sistemtico de generalizacin.
-
Divide y vencers El mtodo divide y vencers consiste en descomponer el problema en una serie de subproblemas de menor tamao, al resolver estos subproblemas usando siempre la misma tcnica, las soluciones parciales se combinan para obtener la solucin del problema original.
-
"Tenemos un problema complejo al cual
dividimos en subproblemas mas pequeos a
resolver. Para resolver cada subproblema
seguimos el mismo procedimiento hasta que
llegamos a un problema que es trivial. Una vez
resueltos los subproblemas los combinamos
para dar solucin al problema original".
De esta forma DyV se expresa de manera
natural mediante un algoritmo recursivo.
-
fun divide_y_venceras(x: problema) dev y:solucin
si pequeo(x) entonces
y:=metodo_directo(x)
si no
{descomponer x en k >= 1 problemas ms pequeos}
{x1, x2, ..., kx}:=descomponer(x)}
{resolver recursivamente los subproblemas}
para j=1 hasta k hacer
yj:= divide_y_venceras(xj)
fin para
{combinar los yj para obtener una solucin y para x}
y:=combinar(y1, ..., yk)
fin si
fin
La funcin pequeo(x) es un predicado
que determina si el tamao del
problema x es suficientemente
pequeo para ser resuelto sin dividir
ms. Si es ese el caso, el problema se
resuelve mediante la funcin
mtodo_directo(x).
-
Para que la aplicacin del mtodo divide y vencers, convenga debe cumplirse que:
1. Las operaciones descomponer y combinar deben ser bastante eficientes.
2. El nmero de subproblemas generados sea pequeo
3. Los subproblemas sean aproximadamente del mismo tamao y no solapen entre s.
La funcin complejidad para un problema de tamao n es un sistema de ecuaciones recurrentes de la forma:
() = ()
() = () + () + ([])
=1
-
Si el problema es de tamao , y los tamaos de los subproblemas 1, 2, , son, respectivamente, 1, 2, , , podemos describir el costo en tiempo del algoritmo divide_y_venceras mediante la
siguiente recurrencia:
() =
, 0
+
=1
, > 0
Donde () es el tiempo del algoritmo divide_y_venceras, () es el tiempo que toma combinar las soluciones y () es el tiempo del metodo_directo.
-
Complejidad de divide y vencers El diseo Divide y Vencers produce algoritmos
recursivos cuyo tiempo de ejecucin se puede expresar mediante una ecuacin en recurrencia del tipo:
= , 1 <
(/) + ,
, son nmeros reales y son nmeros naturales, > , > , > representa el nmero de subproblemas. / es el tamao de cada uno de ellos. representa el costo de descomponer el problema inicial
en los subproblemas y el de combinar las soluciones para producir la solucin del problema original, o bien el de resolver un problema elemental.
-
La solucin a esta ecuacin, puede alcanzar distintas complejidades.
=
()
( log )
()
<
=
>
Las diferencias surgen de los distintos valores que pueden tomar y , que en definitiva determinan el nmero de subproblemas y su tamao. Lo importante es observar que en todos los casos la complejidad es de orden polinmico o polilogartmico pero nunca exponencial.
Los algoritmos recursivos pueden alcanzar una complejidad exponencial en muchos casos. Esto se debe normalmente a la repeticin de los clculos que se produce al existir solapamiento en los subproblemas en los que se descompone el problema original.
-
Ejemplo 01: Bsqueda del mximo y del mnimo
Mtodo directo
MaxMin (A: array [1..N] of tipo; var Max, Min: tipo)
Max = A[1]
Min = A[1]
para i=2, 3, ..., N
si A[i]>Max
Max = A[i]
en otro caso si A[i]
-
Divide y vencers
MaxMinDV (i, j: integer; var Max, Min: tipo)
si iMax2
Max= Max1
en otro caso
Max = Max2
si Min1A[j]
Max = A[i] ; Min = A[j]
en otro caso
Max = A[j] ; Min= A[i]
en otro caso
Max = A[i] ; Min = Max
Operacin bsica:
Asignaciones a Max, Min,
Max1, Min1, Max2 y Min2.
Complejidad temporal
Peor caso: Los nmeros
estn hasta el final el
mximo y el mnimo.
= 2, 1 22(/2) + 2, > 2
() ()
-
En el ejemplo anterior la complejidad temporal no
obtuvo un beneficio al utilizar un algoritmo que
emplea la tcnica de DyV, si se piensa como una
aplicacin a funcionar bajo la idea de un proceso
monoprocesador, pero si se considera que la
solucin de los problemas parciales es
independiente y se utiliza una idea de
procesamiento paralelo, probablemente el
potencial de un algoritmo como este se vera
reflejado en los tiempos de procesamiento de
problemas para n muy grandes.
-
Ejemplo 02: Ordenamiento de un arreglo
Mtodo directo (Ej. Insercin)
Procedimiento Insercion(A,n)
{
para i=1 hasta itemp)&&(j>=0)) hacer
A[j+1]=A[j]
j--
fin mientras
A[j+1]=temp
fin para
fin Procedimiento
Operacin bsica: Movimientos en el arreglo y comparaciones
entre un elemento y temp Complejidad temporal
Peor caso: Los nmeros estn ordenados y se compara un
elemento con todos los elementos del arreglo . = ( 1) (2)
-
Divide y vencers (Mergesort)
MaxMinDV (i, j: integer; var Max, Min: tipo)
si iMax2
Max= Max1
en otro caso
Max = Max2
si Min1A[j]
Max = A[i] ; Min = A[j]
en otro caso
Max = A[j] ; Min= A[i]
en otro caso
Max = A[i] ; Min = Max
Operacin bsica:
Asignaciones a Max, Min,
Max1, Min1, Max2 y Min2.
Complejidad temporal
Peor caso: Los nmeros
estn hasta el final el
mximo y el mnimo.
= 2, 1 22(/2) + 2, > 2
() ()
-
Observaciones sobre Divide y Vencers 1. En primer lugar, el nmero k debe ser
pequeo e independiente de una entrada determinada.
En el caso particular de los algoritmos Divide y Vencers que contienen slo una llamada recursiva, es decir k=1, hablamos de algoritmos de simplificacin.
Tal es el caso del algoritmo recursivo que resuelve el clculo del factorial de un nmero, que sencillamente reduce el problema a otro subproblema del mismo tipo de tamao ms pequeo.
Tambin es un algoritmo de simplificacin el de bsqueda binaria en un vector.
-
El algoritmo de bsqueda binaria es un ejemplo de un algoritmo de simplificacin, pero posee la caracterstica de dividir el problema para alcanzar la solucin de una manera ms simple.
Bsqueda binaria
-
2. Desde un punto de vista de la eficiencia de
los algoritmos Divide y Vencers, es muy
importante conseguir que los subproblemas
son independientes, es decir, que no existe
solapamiento entre ellos.
Si la solucin de los subproblemas no es
independiente el tiempo de ejecucin de estos
algoritmos ser exponencial.
Tal es el caso la serie de Fibonacci, la cual, a pesar de ajustarse al esquema general y de tener slo dos llamadas
recursivas, tan slo se puede considerar un algoritmo
recursivo pero no clasificarlo como diseo Divide y
Vencers.
-
3. Debe haber reparto de carga, es decir, la
divisin de los subproblemas debe ser lo
ms equilibrada posible.
Si la solucin de los subproblemas no tiene un coste
similar para todos puede pasar que el coste caiga en
un coste poco beneficioso que si se resolviera con el
algoritmo clsico.
Tal es el caso del algoritmo de ordenacin rpida, si al realizar la particin del vector nos encontramos con que el
pivote queda casi al principio o al final del vector,
tendremos que el tiempo de ejecucin del algoritmo est en
(2), mientras que si esta prximo a la mitad del vector, estar en ( log ()).
-
Ejercicios: Algoritmos de ordenamiento (Mergesort y Quicksort)
1. Implementar en ANSI C el algoritmo de ordenamiento
Mergesort y Quicksort, utilizar el archivo de 10,000,000
de nmeros y mostrar los tiempos del ordenamiento de
cada algoritmo para los primeros 1000, 10000,
100000, 1000000 y 10000000 nmeros.
2. Buscar un polinomio de grado 1 y 2 para aproximar los
tiempos de cada algoritmo.
* Entregar con la rbrica de reporte de prctica.