You are on page 1of 38

Estrategias para el diseño de

Algoritmos
 Las estrategias más comunes para el
diseño de algoritmos son: voraz, divide
y vencerás, programación dinámica y
backtracking.

1
Algoritmo voraz
 También conocido como ávido, devorador o
goloso.
 Los algoritmos voraces suelen ser bastante
simples. Se emplean sobre todo para resolver
problemas de optimización, como por ejemplo,
encontrar la secuencia óptima para procesar un
conjunto de tareas por un computador, hallar el
camino mínimo de un grafo, etc.

2
Algoritmo voraz
 Habitualmente, los elementos que intervienen son: un conjunto o lista de
candidatos (tareas a procesar, vértices del grafo, etc);
 un conjunto de decisiones ya tomadas (candidatos ya escogidos);
 una función que detemina si un conjunto de candidatos es una solución
al problema (aunque no tiene por qué ser la óptima);
 una función que determina si un conjunto es completable, es decir, si
añadiendo a este conjunto nuevos candidatos es posible alcanzar una
solución al problema, suponiendo que esta exista;
 una función de selección que escoge el candidato aún no seleccionado
que es más prometedor;
 una función objetivo que da el valor/costo de una solución (tiempo total
del proceso, la longitud del camino, etc) y que es la que se pretende
maximizar o minimizar;

3
Algoritmo voraz
 Para resolver el problema de optimización hay que encontrar un
conjunto de candidatos que optimiza la función objetivo. Los
algoritmos voraces proceden por pasos. Inicialmente el conjunto
de candidatos es vacío. A continuación, en cada paso, se intenta
añadir al conjunto el mejor candidato de los aún no escogidos,
utilizando la función de selección. Si el conjunto resultante no es
completable, se rechaza el candidato y no se le vuelve a considerar
en el futuro. En caso contrario, se incorpora al conjunto de
candidatos escogidos y permanece siempre en él. Tras cada
incorporación se comprueba si el conjunto resultante es una
solución del problema. Un algoritmo voraz es correcto si la solución
así encontrada es siempre óptima.

4
Algoritmo voraz
 El esquema genérico del algoritmo voraz es:

5
Algoritmo voraz
 El nombre voraz proviene de que, en cada paso, el
algoritmo escoge el mejor "pedazo" que es capaz de
"comer" sin preocuparse del futuro. Nunca deshace
una decisión ya tomada: una vez incorporado un
candidato a la solución permanece ahí hasta el final;
y cada vez que un candidato es rechazado, lo es para
siempre.

6
Algoritmo voraz
 Los algoritmos Voraces: Son algoritmos de órdenes bajos.
 Los algoritmos Voraces: Se basan en hacer elecciones a partir
de un conjunto de opciones.
 En los algoritmos Voraces: La función selección determina la
mejor opción del conjunto de opciones.
 En los algoritmos Voraces: La función factible determina si un
conjunto de opciones seleccionadas puede convertirse en una
solución.
 Ejemplo de este tipo de algoritmos: Kruskal, Dijskstra, Prim.

7
Algoritmo voraz
Ejemplo:
 Se desea pagar una cantidad de dinero a un cliente empleando el menor
número posible de monedas. Los elementos del esquema anterior se
convierten en:
 candidato: conjunto finito de monedas de, por ejemplo, 1, 5, 10 y 25
unidades, con una moneda de cada tipo por lo menos;
 solución: conjunto de monedas cuya suma es la cantidad a pagar;
 completable: la suma de las monedas escogidas en un momento dado no
supera la cantidad a pagar;
 función de selección; la moneda de mayor valor en el conjunto de candidatos
aún no considerados;
 función objetivo: número de monedas utilizadas en la solución.

8
Backtracking
 Técnica general de resolución de problemas, que suele
aplicarse sobre todo a juegos y problemas de óptimización.
 Realiza una búsqueda exhaustiva y sistemática en el espacio
de soluciones del problema.
 Busca todas las posibles soluciones.
 La solución de un problema de backtracking se puede
expresar como una tupla (x1,x2,…,xn), que satisface una
restricciones R(x1,x2,…,xn) y a veces optimizando una función
objetivo.

9
Backtracking
 En cada momento el algoritmo se encontrará en un cierto
nivel k, con una solución parcial (x1,x2,…,xk) (con k<=n).
 Si puede añadirse un elemento xk+1 a la solución parcial se avanza
al nivel k+1.
 Si no se prueban otros valores válidos para xk.
 Si no existe ningún valor que sea válido por probar, se retrocede al
nivel anterior k-1.
 Se continua con este proceso hasta que la solución parcial sea una
solución del problema o hasta que no queden más posibilidades por
probar (en el caso de que no se encuentre ninguna solución o se
busquen todas las soluciones del problema).

10
Backtracking
• Se separa la búsqueda en varias búsquedas parciales o
subtareas.

• Asimismo, estas subtareas suelen incluir más subtareas.


• El tratamiento general de estos algoritmos es de naturaleza
recursiva.

• ¿Por qué se llaman algoritmos de vuelta atrás?. Porque en el


caso de no encontrar una solución en una subtarea se
retrocede a la subtarea original y se prueba otra cosa distinta
(una nueva subtarea distinta a las probadas anteriormente).

11
Backtracking
Es un método sistemático que realiza una búsqueda
exhaustiva de las soluciones, pero esta búsqueda no
es caótica, sino organizada.

Puede obtener una o todas las respuestas factibles o


bien la respuesta óptima entre todas las factibles.

Ejemplos de problemas: Coloreado de un grafo, ocho


reinas.

12
Backtracking

13
Backtracking
• En general representamos la solución como un
vector a = (a1,a2,...,an), donde:
• Cada ai es seleccionado de un conjunto Si.
Puede representar, por ejemplo:
• Una situación donde ai es el i-ésimo elemento de una
permutación.
• Un subconjunto (ai es verdadero sii el i-ésimo elemento
del universo pertenece al conjunto.
• Secuencia de movimientos en un juego o camino en un
grafo, donde ai contiene el i-ésimo evento en la
secuencia.

14
Backtracking
 Problemas que consideraremos:
 Problemas de Decisión: Búsqueda de las soluciones que satisfacen
ciertas restricciones.
 Problemas de Optimización: Búsqueda de la mejor solución en base a
una función objetivo.
 Cada solución es el resultado de una secuencia de decisiones.
 En algunos problemas de este tipo se conoce un criterio óptimo de selección
en cada decisión: técnica voraz
 En otros problemas se cumple el principio de optimalidad de Bellman y se
puede aplicar la técnica de la programación dinámica.
 Existen otros problemas en los que no hay más remedio que buscar.

15
Backtracking
 En definitiva, el algoritmo realiza una búsqueda en
profundidad en el árbol de soluciones del problema.

x1

x2

x3

16
Backtracking
 En definitiva, el algoritmo realiza una búsqueda primero en
profundidad en el árbol de soluciones del problema.

x1 2 10 14

x2 3 6 7 11 12 15 16

x3 4 5 8 9 13 17 18

17
Backtracking. Ejemplo
Problema 8-Reinas

 El problema de las 8-Reinas consiste en colocar 8 reinas en


un tablero de ajedrez de tamaño 8*8 de forma la reinas no se
amenacen según las normas del ajedrez. Se busca encontrar
una solución o todas las soluciones posibles.
 Este problema puede resolverse utilizando un esquema de
backtracking.
 Cualquier solución del problema estará formada por una
n-tupla (x1,x2,…,xn), dónde cada xi indica la columna donde
la reina de la fila i-ésima es colocada.

18
Backtracking. Ejemplo
Problema 8-Reinas
 Diferencia entre fuerza bruta y búsqueda con retroceso:
si se comprueba que (x1,…,xi) no puede
conducir a ninguna solución, se evita formar las ti+1 tn tuplas que
comienzan por
(x1,…,xi)

 Para saber si una n-tupla es solución, suele haber dos tipos de


restricciones:
 explícitas: describen el conjunto Ci de
valores que puede tomar xi (todas las tuplas que satisfacen estas
restricciones definen un espacio de soluciones posibles);
 implícitas: describen las relaciones que deben cumplirse entre los xi
(qué soluciones posibles satisfacen el predicado

19
Backtracking. Ejemplo
Problema 8-Reinas
 El problema consiste en colocar ocho reinas en
un tablero de ajedrez sin que se den jaque
(dos reinas se dan jaque si comparten fila,
columna o diagonal).

20
Backtracking. Ejemplo
Problema 8-Reinas
64
 Formulación 1: 4.426.165.368
8

 Formulación 2: Puesto que no puede haber más de una reina por


fila, podemos replantear el problema como:
“colocar una reina en cada fila del tablero de forma que no se den
jaque”.
En este caso, para ver si dos reinas se dan jaque basta con ver si
comparten columna o diagonal.
Por lo tanto, toda solución del problema puede representarse con una
8-tupla (x1,…,x8) en la que xi es la columna en la que se coloca la
reina que está en la fila i del tablero.
El espacio de soluciones consta de
88 8-tuplas (16.777.216 8-tuplas)
21
Backtracking. Ejemplo
Problema 8-Reinas

 Formulación 3: Puesto que no puede haber


más de una reina por columna, sólo hace falta
que consideremos las 8-tuplas (x1,…,x8) que
sean permutaciones de (1,2,...,8)
El espacio de soluciones consta de
8! 8-tuplas (40.320 8-tuplas)

22
Backtracking. Ejemplo
Problema 8-Reinas

 Volviendo al planteamiento general:


 Para facilitar la búsqueda, se adopta una
organización en árbol del espacio de
soluciones.

 En el ejemplo, con la 2ª formulación y


para el problema de las cuatro reinas
(en un tablero 4 4):
23
algoritmo BackTracking(ent k:entero;
entsal X:vector[1..n]de valor)
{Pre: X[1..k-1] es completable}
variable v:valor
para todo v en Ci hacer
X[k]:=v;
si completable(X,k) entonces
si Sol(X,k) entonces
guardar(X,k)
fsi;
si k<n entonces
BackTracking(k+1,X)
La llamada inicial es
fsi;
...
fsi BackTracking(1,X);
fpara ...

24
Backtracking. Ejemplo
Problema 4-Reinas
 Nótese que el árbol no se construye
explícitamente sino implícitamente mediante las llamadas
recursivas del algoritmo de búsqueda.

 El algoritmo no hace llamadas recursivas cuando:


 k = n+1, o cuando
 el nodo generado no es completable (PODA).

Backtracking :búsqueda primero en profundidad (DFS) en un


árbol y con detección de soluciones parciales no
completables (poda)
25
Backtracking. Ejemplo
Problema 4-Reinas

 Las restricciones para este problema consisten en que dos


reinas no pueden colocarse en la misma fila, ni en la misma
columna ni en la misma diagonal.
 Por ejemplo, el problema de las 4-Reinas tiene dos posibles
soluciones: [2,4,1,3] y [3,1,4,2].

26
Backtracking. Ejemplo
Problema 4-Reinas

27
Backtracking. Ejemplo
Problema 4-Reinas
1

2 6
10 14

3 15
7
17
4 11

16
8 12
5

13
9

Soluciones 28
Programación Dinámica
Es una técnica ascendente (bottom-up): se empieza con
los subcasos más pequeños (y sencillos) y se combinan
sus soluciones obteniendo respuestas para subcasos de
tamaños cada vez mayores, hasta que finalmente se
llega a la solución del caso original.

Los algoritmos de Programación Dinámica: Pretenden


evitar las repeticiones que se crean en la propia
definición del problema.

29
Programación Dinámica

Los algoritmos de Programación Dinámica:


•Regularmente utilizan más recursos de memoria
•El algoritmo se basa en una definición recursiva
del problema, aunque el algoritmo en sí no es
necesariamente recursivo.
•Ejemplos: Fibonacci, Cálculo de combinaciones,

30
Divide y vencerás

La técnica de diseño de algoritmos llamada "divide y


vencerás" (divide and conquer) consiste en
descomponer el problema original en varios sub-
problemas más sencillos, para luego resolver éstos
mediante un cálculo sencillo. Por último, se combinan
los resultados de cada sub-problema para obtener la
solución del problema original.

31
Divide y vencerás
Los algoritmos de Divide y Vencerás:
Típicamente son algoritmos recursivos.
Dividen el problema en subproblemas ajenos del mismo
tipo que el problema original.
Resuelven el problema en base a soluciones de casos
mas simples del mismo problema.
Suelen combinarse con algoritmos mas simples para
mejorar el desempeño.
Tiene que ser posible descomponer el caso en subcasos
y recomponer las soluciones parciales de forma eficiente.

32
Divide y vencerás

Esta técnica es la base de los algoritmos eficientes para


casi cualquier tipo de problema como, por ejemplo:
Puntos más cercanos, algoritmos de ordenamiento
(quicksort, mergesort, entre muchos otros), multiplicar
números grandes (Karatsuba), multiplicación de
matrices, análisis sintácticos (analisis sintáctico top-
down) y la transformada discreta de Fourier.

33
Algoritmos Probabilistas
Los algoritmos probabilísticos o probabilistas son aquellos
que basan el resultado devuelto en decisiones aleatorias, de
tal forma que, en promedio se obtienen una buena solución
al problema planteado, dada una distribución de datos de
entrada.
Su precisión mejora a medida que crece el tiempo disponible
para el algoritmo.
El análisis de los algoritmos probabilistas es, a menudo, muy
difícil.
Ejemplos: Integración Numérica Aproximada, comprobación
de primalidad

34
Algoritmos Probabilistas

Se pueden distinguir fundamentalmente cuatro grandes


categorías:

* Algoritmos numéricos, que devuelvan una


aproximación al resultado, frecuentemente en forma de
intervalo. Son útiles cuando la solución exacta es
demasiado costosa (o directamente imposible de
calcular, como por ejemplo, para números irracionales)
y una aproximación es lo suficientemente buena. Este
tipo de algoritmos suelen ofrecer resultados más
precisos cuanto mayor tiempo se dedica a su cálculo.
35
Algoritmos Probabilistas

* Algoritmos de Monte Carlo, que siempre


devuelven una solución aunque esta a veces no sea
correcta. Son útiles cuando una aproximación no es
suficiente (por ejemplo, en un problema de
decisión). Cuentan con el inconveniente de no
saber con exactitud si la respuesta es acertada,
pues sólo existe una cierta probabilidad de éxito.
Cuantas más veces se ejecute, más seguro se
estará de la corrección de la solución.

36
Algoritmos Probabilistas
* Algoritmos de Las Vegas, similares a los de Monte Carlo
pero que nunca devuelven una solución errónea, con el
inconveniente de que pueden no terminar o devolver
solución. Esto garantiza que la respuesta sea la buena,
pero no garantiza que el algoritmo funcione. Como en los
casos anteriores, cuanto mayor es el tiempo dedicado al
cálculo, más fiable es la solución. No debe confundirse este
tipo de algoritmos con aquellos deterministas, como el
simplex en programación lineal, que son muy eficientes
para la mayoría de los posibles datos de entrada pero
desastrosos para unos pocos. Nótese que dichos algoritmos
siempre devuelven una solución correcta.
37
Algoritmos Probabilistas

* Algoritmos de Sherwood, los cuales


devuelven siempre una respuesta, la cual es
forzosamente exacta. Aparecen cuando un
algoritmo determinista conocido es más
rápido en el caso medio que en el peor. El uso
del azar permite reducir, e incluso eliminar, la
diferencia entre buenos y malos ejemplares.

38

You might also like