Está en la página 1de 46

ALGORITMOS DIVIDE Y VENCERÁS

ALGORITMOS FUNDAMENTALES TSI343


ALGORITMOS DIVIDE Y VENCERÁS

Diseño de algoritmos
• Es una labor creativa.

• Se requiere de experiencia y, con frecuencia, de varios intentos.

• Podría pensarse en la necesidad de un análisis por separado de cada problema en


particular y crear desde cero un algoritmo que lo resuelva.
ALGORITMOS DIVIDE Y VENCERÁS

Definición del paradigma divide y vencerás

• Es una técnica de diseño de algoritmos que resuelve un problema a partir de la


solución de subproblemas del mismo tipo, pero de menor tamaño.
• Posteriormente se combinan los resultados parciales para obtener la solución del
problema original.
• Si los subproblemas son todavía relativamente grandes, se aplica de nuevo esta
técnica hasta alcanzar subproblemas lo suficientemente pequeños como para
encontrar una solución directa.
• Para aplicar esta técnica se requiere que los subproblemas sean del mismo tipo que
el problema original.
ALGORITMOS DIVIDE Y VENCERÁS

Definición del paradigma divide y vencerás


• Si el problema x es de tamaño n y los tamaños de los subproblemas x1, x2,…, xk
son, respectivamente n1, n2,…, nk, describiremos el tiempo de ejecución T(n) del
algoritmo divide y vencerás por medio de la siguiente ecuación de recurrencia.

Donde T(n) es el tiempo del algoritmo divide y vencerás


cuando el problema de entrada es de tamaño n.
n0 es el tamaño umbral que indica que ya no se va a
subdividir el problema en partes más pequeñas,.
g(n) es el tiempo del método directo y f(n) es el tiempo de
descomponer en subproblemas y combinar los resultados
de éstos.
PASOS DE DIVIDE Y VENCERÁS

1.- Plantear el problema de forma que pueda descomponerse en k subproblemas del


mismo tipo, pero de menor tamaño. Es decir, si el tamaño de la entrada es n, debemos
dividir el problema en k subproblemas (donde 1 < k ≤ n) cada uno con una entrada
cuyo tamaño aproximado es de n/k. A esta tarea se le conoce como división.

2.- Resolver independientemente todos los subproblemas, ya sea directamente si son


elementales o bien de forma recursiva. El hecho de que el tamaño de los subproblemas
sea estrictamente menor que el tamaño original del problema nos garantiza la
convergencia hacia los casos elementales, también denominados casos base, en los que
se utiliza un método directo para obtener la solución..
PASOS DE DIVIDE Y VENCERÁS

1.- Plantear el problema de forma que pueda descomponerse en k subproblemas del


mismo tipo, pero de menor tamaño. Es decir, si el tamaño de la entrada es n, debemos
dividir el problema en k subproblemas (donde 1 < k ≤ n) cada uno con una entrada
cuyo tamaño aproximado es de n/k. A esta tarea se le conoce como división.

2.- Resolver independientemente todos los subproblemas, ya sea directamente si son


elementales o bien de forma recursiva. El hecho de que el tamaño de los subproblemas
sea estrictamente menor que el tamaño original del problema nos garantiza la
convergencia hacia los casos elementales, también denominados casos base, en los que
se utiliza un método directo para obtener la solución.
PASOS DE DIVIDE Y VENCERÁS

3.- Combinar las soluciones obtenidas en el paso anterior para construir la solución del
problema original.

Características deseables
• Los subproblemas deben ser independientes, es decir, que no exista traslape entre
ellos. De lo contrario, el tiempo de ejecución de estos algoritmos será exponencial.
• El reparto de la carga entre los subproblemas, debe ser de forma equilibrada, las
operaciones que descomponen el problema en otros más sencillos y las operaciones
que combinan las soluciones parciales deben ser bastante eficientes.
• El número de subproblemas que se generen no debe ser grande.
EJEMPLOS DE DIVIDE Y VENCERÁS
Las torres de Hanoi
• Consiste en pasar los discos, uno por uno (o uno a la vez), del poste A, al poste B con la condición de no poner
un disco más grande sobre otro más pequeño.
• Se puede utilizar el poste C como auxiliar. http://www.softschools.com/games/logic_games/tower_of_hanoi/

Figura 1
EJEMPLOS DE DIVIDE Y VENCERÁS

• Si intentamos describir la solución del problema para una torre de 4 o más discos, la
descripción resultaría muy complicada, sin embargo, si aplicamos el enfoque de
divide y vencerás, entonces la solución es mucho más clara.
• El problema de pasar los n discos más pequeños de A a B se reduce a lo siguiente:
considerar el problema como dos problemas de tamaño n-1. Primero se mueven los
n-1 discos más pequeños del poste A al C, dejando el n-esimo disco en el poste A. Se
mueve este disco de A a B y, finalmente se mueven los n-1 discos más pequeños de
C a B. El movimiento de los n-1 discos más pequeños se efectuará por medio de la
aplicación recursiva del método, pero utilizando el poste no ocupado como auxiliar.
EJEMPLOS DE DIVIDE Y VENCERÁS
• En la Figura se ilustra como pasar los n-1 discos al poste auxiliar C, de tal forma que el disco más
grande queda libre para ponerlo hasta abajo del poste B.
• En la Figura 2 se ilustra el paso del disco más grande al poste B. Ahora, el problema se reduce a pasar
los n-1 discos del poste C al B, lo cual se hace de manera similar a la secuencia presentada en la
Figura 1.

Figura 2
EJEMPLOS DE DIVIDE Y VENCERÁS
• La solución es sencilla de entender con este enfoque, aunque se complica al llevarla a la práctica
conforme aumenta el número de discos a mover de A a B. El tiempo de ejecución de este algoritmo
es el siguiente.

• El tiempo de ejecución T(n) para pasar n discos del poste A al poste B es la suma del tiempo T(n-1)
para pasar n-1 discos de A a C, más el tiempo T(1) para pasar el disco n a B, más el tiempo T(n-1)
para pasar los n-1 discos de C a B. El caso base se presenta cuando solo hay que mover un disco.
EJEMPLOS DE DIVIDE Y VENCERÁS
• El funcionamiento de los algoritmos que siguen la técnica de Divide y Vencerás descrita
anteriormente se refleja en el esquema general que presentamos a continuación:
EL MÉTODO MERGESORT (ORDENAMIENTO POR MEZCLA, FUSIÓN)
• Es una aplicación clásica de la estrategia para resolución de algoritmos "divide y vencerás".

• Se basa en la idea de que secuencias ordenadas se pueden unir (o hacerles un merge) en tiempo
lineal.

• Se van separando los arreglos hasta llegar a pedazos de longitud 2, que se pueden ordenar fácilmente.

• Luego se van ordenando los pedazos cada vez más grandes.

• Es un algoritmo recursivo con un número de comparaciones mínimo.

• El tiempo de ejecución promedio es O(N log(N)).

• Su desventaja es que trabaja sobre un array auxiliar lo cual tiene dos consecuencias:
Uso de memoria extra y trabajo extra consumido en las copias entre arreglos (aunque es un trabajo
de tiempo lineal).
EL MÉTODO MERGESORT
Primera Etapa
• La primera etapa consiste en dividir el problema hasta llegar a un tamaño que resulta más fácil de
resolver
EL MÉTODO MERGESORT
Segunda Etapa
• Luego se va armando (combinando) los resultados parciales
EL MÉTODO MERGESORT
Código del Algoritmo
EL MÉTODO MERGESORT
Código del Algoritmo
EL MÉTODO MERGESORT
Código del Algoritmo
EL MÉTODO MERGESORT
Código del Algoritmo
EL MÉTODO MERGESORT
Código del Algoritmo
EL MÉTODO MERGESORT
Código del Algoritmo
EL MÉTODO MERGESORT
Análisis del ordenamiento
• El ordenamiento por mergesort es un ejemplo clásico de las técnicas usadas para analizar programas
recursivos.

• Escribiremos una relación de recurrencia para el cálculo del tiempo de ejecución.

• Asumimos n es potencia de 2 de modo que siempre dividimos la entrada en dos mitades. Para n = 1
el tiempo es constante, luego lo denotaremos por 1.

• En otro caso el tiempo de ordenar n números es igual al tiempo de realizar dos ordenamientos
recursivos de tamaño n=2, más el tiempo de fusión que es lineal.
EL MÉTODO MERGESORT
Análisis del ordenamiento
• El ordenamiento por mergesort es un ejemplo clásico de las técnicas usadas para analizar programas
recursivos.

• Escribiremos una relación de recurrencia para el cálculo del tiempo de ejecución.

• Asumimos n es potencia de 2 de modo que siempre dividimos la entrada en dos mitades. Para n = 1
el tiempo es constante, luego lo denotaremos por 1.

• En otro caso el tiempo de ordenar n números es igual al tiempo de realizar dos ordenamientos
recursivos de tamaño n=2, más el tiempo de fusión que es lineal.
EL MÉTODO QUICKSORT
• Es el algoritmo de ordenación ascendente de elementos de un arreglo más rápido
(en la práctica) conocido.
• Su tiempo de ejecución promedio es O(N log(N)).
• Para el peor caso tiene un tiempo O(N^2), pero si se codifica correctamente las
situaciones en las que sucede el peor caso pueden hacerse altamente improbables.
• En la práctica, el hecho de que sea más rápido que los demás algoritmos de
ordenación con el mismo tiempo promedio O(N log(N)) está dado por un ciclo
interno muy ajustado (pocas operaciones).
• Al igual que el algoritmo de ordenación por intercalación (mergesort), el algoritmo
de ordenación rápida es fruto de la técnica de resolución de algoritmos "divide y
vencerás".
• Se basa en cada recursión, dividir el problema en subproblemas más pequeños,
resolverlos cada uno por separado (aplicando la misma técnica) y unir las soluciones.
EL MÉTODO QUICKSORT
Pasos para la implementación

1. Si el array de datos es vacío o tiene un sólo elemento no hacemos nada y salimos


de la recursión.
2. Elegimos un elemento v (llamado pivote) del array de datos.
3. Particionamos el array de datos A en tres arrays:
• A1={todos los elementos de A - {v} que sean menores o iguales que v}
• A2={v}
• A3={todos los elementos de A - {v} que sean mayores o iguales que v}
4. Aplicamos la recursión sobre A1 y A3
5. Realizamos el último paso de "divide y vencerás" que es unir todas las soluciones
para que formen el array A ordenado. Dado que a este punto A1 y A3 están ya
ordenados, concatenamos A1, A2 y A3.
EL MÉTODO QUICKSORT
Elección del Pivote
• La eficiencia de este algoritmo dependerá de cómo elegimos el pivote v ya que este
determina las particiones del array de datos.
• Lo que quiere lograr es elegir el pivote v tal que las particiones A1 y A3 sean de
tamaños (cantidad de elementos) lo más iguales posible.
• Dado que el array de datos está desordenado, se podría elegir el primer elemento
del array como pivote. Esto funcionaría bien si los datos estuvieran uniformemente
distribuidos en el array. Sin embargo, no podemos suponer esto: al algoritmo se le
podría estar pasando un array "casi ordenado", y elegir el primer elemento como
pivote resultaría, en este caso, desastroso ya que A1 sería muy pequeño comparado
con A3.
• Por la misma razón, elegir el último elemento del array como pivote también es una
mala idea.
EL MÉTODO QUICKSORT
• Se puede elegir el pivote al azar entre los elementos del array de datos. Sin embargo,
la elección de números aleatorios es un proceso costoso e incrementa el tiempo de
ejecución del algoritmo.
• Una estrategia es elegir como pivote la mediana de los elementos de la izquierda, la
derecha y el centro, es decir, si el array de datos es A, la mediana del conjunto { A[0],
A[N-1], A[(N-1)/2] }. Por ejemplo, si nuestro array de datos fuera 6 8 1 3 10 2 9, el
pivote es la mediana de { 6, 9, 3 } o sea 6. Esto determinará las particiones A1={1, 3,
2}, A2={ 6 } y A3={ 8, 10, 9 }.
• Es importante tener en cuenta que esta estrategia de elección del pivote no dará la
mejor elección: simplemente nos asegura que, en promedio, la elección del pivote es
buena.
EL MÉTODO QUICKSORT
Ejemplo 1: Implementación
Parte I
EL MÉTODO QUICKSORT
Parte II
EL MÉTODO QUICKSORT
Parte III
EL MÉTODO QUICKSORT
Parte III
EL MÉTODO QUICKSORT
Parte III
EL MÉTODO QUICKSORT

Ejemplo 2: Implementación
EL MÉTODO QUICKSORT
Análisis eficiencia de algoritmo quicksort
• La eficiencia del algoritmo depende de la posición en la que termine el pivote elegido.

• Coste en tiempo en el caso mejor. El coste en este caso es (n log n) y corresponde a remplazar k por n/2 en la
recurrencia anterior. En este caso estaríamos dividiendo el vector en dos subvectores del mismo tamaño e
intuitivamente es la forma más rápida de ordenar el vector.

• Coste en tiempo en el caso promedio. El coste en este caso es (n log n). Para calcularlo se ha de suponer una
distribución de probabilidad de las entradas. Es común suponer en este caso que todas las permutaciones del vector
de entrada son equiprobables y que por tanto todos los elementos tienen igual probabilidad (1/n) de ser el pivote.

• Coste en tiempo en el caso peor. El caso peor de quick–sort sucede cuando el vector de entrada est´a ordenado
creciente o decrecientemente. En este caso se divide el vector en un subvector de tamaño 1 y otro de tamaño n −
1. Intuitivamente parece que que no estamos reduciendo suficientemente el tamaño del problema pues hemos de
ordenar un vector casi del mismo tamaño del original. Reemplazando este valor de k (k = 1) en la recurrencia
anterior puede verse que el coste en este caso es (n^2).
EL MÉTODO QUICKSORT
Análisis eficiencia de algoritmo quicksort
• La mejor forma de ilustrar y calcular la complejidad del algoritmo es considerar el número de comparaciones
realizadas teniendo en cuenta circunstancias ideales.
• Supongamos que n (número de elementos de la lista) es una potencia de 2, n = 2^k (k = log2 n).
• Supongamos que el pivote es el elemento central de cada lista, de modo que quicksort divide la sublista en dos
sublistas aproximadamente iguales.
• En la primera exploración o recorrido hay n − 1 comparaciones. El resultado de la etapa crea dos sublistas
aproximadamente de tamaño n/2.
• En la siguiente fase, el proceso de cada sublista requiere aproximadamente n/2 comparaciones. Las comparaciones
totales de esta fase son 2(n/2) = n.
• La siguiente fase procesa cuatro sublistas que requieren un total de 4(n/4) comparaciones, etc.
• Eventualmente, el proceso de división termina después de k pasadas cuando la sublista resultante tenga tamaño 1.
• El número total de comparaciones es aproximadamente:
EL MÉTODO DE BÚSQUEDA BINARIA
• El algoritmo de búsqueda binaria es un ejemplo claro de la técnica divide y vencerás, se utiliza
para búsquedas en el diccionario o en un directorio telefónico.

• Es un algoritmo de simplificación, ya que el problema se va reduciendo con cada paso, con lo


que se obtiene un tiempo de ejecución en el orden logarítmico.

• Se requiere que los elementos dentro del arreglo en donde se hará la búsqueda se encuentren
ordenados, ya sea de manera ascendente o descendente.

• Puede tener dos enfoques: recursivo y no recursivo.

• El algoritmo recursivo tiene un tiempo de ejecución mayor que el de los no recursivos, aunque
del mismo orden O(log(n)). Además tiene mayor complejidad espacial, debido a que requieren
más memoria (para guardar la pila de recursión).
EL MÉTODO DE BÚSQUEDA BINARIA
Enfoque recursivo:

Sea x el número buscado.

• si (a[mitad] = x) entonces se encontró el elemento buscado.

• si (a[mitad] > x) hacer la búsqueda binaria en la mitad inferior del arreglo.

• si (a[mitad] < x) hacer la búsqueda binaria en la mitad superior del arreglo.


EL MÉTODO DE BÚSQUEDA BINARIA
Pseudocódigo del enfoque recursivo.
EL MÉTODO DE BÚSQUEDA BINARIA
Código en C del enfoque recursivo.
EL MÉTODO DE BÚSQUEDA BINARIA
Psedocódigo del enfoque no recursivo de la búsqueda binaria.
EL MÉTODO DE BÚSQUEDA BINARIA
Código en C del enfoque no recursivo de la búsqueda binaria.
EL MÉTODO DE BÚSQUEDA BINARIA
Tiempo de ejecución de la búsqueda binaria no recursiva
En la función BusquedaBinariaNoRecursiva, el peor de los casos se presenta cuando el número
buscado no se encuentra, es decir, cuando prim > ult. Con cada iteración, el número de
elementos que todavía pueden coincidir con el número buscado se reduce aproximadamente a la
mitad. Las iteraciones terminan cuando el número de elementos que todavía pueden coincidir es
1. Sea k el número máximo de iteraciones. Se debe cumplir que
EL MÉTODO DE BÚSQUEDA BINARIA
donde n es el tamaño del arreglo.
Entonces, cuando k cumple con lo anterior,
el algoritmo seguro termina aunque puede
terminar antes si encuentra el dato. Por
esto, 𝑘 ∈ 𝑂(log(𝑛)). En la siguiente Figura se
observa que el número máximo de
iteraciones que se realizan con el programa
de búsqueda binaria crece
logarítmicamente con el tamaño del
arreglo.
EL MÉTODO DE BÚSQUEDA BINARIA
donde n es el tamaño del arreglo.
Entonces, cuando k cumple con lo anterior,
el algoritmo seguro termina aunque puede
terminar antes si encuentra el dato. Por
esto, 𝑘 ∈ 𝑂(log(𝑛)). En la siguiente Figura se
observa que el número máximo de
iteraciones que se realizan con el programa
de búsqueda binaria crece
logarítmicamente con el tamaño del
arreglo.
EL MÉTODO DE BÚSQUEDA BINARIA
Tiempo de ejecución de la búsqueda binaria recursiva
La ecuación de recurrencia para la búsqueda binaria es la siguiente:
EL MÉTODO DE BÚSQUEDA BINARIA
Ejemplo

También podría gustarte