Algoritmos voraces

Anuncio
PARTE II: ALGORÍTMICA
Tema 4. Algoritmos voraces.
4.1. Método general.
4.2. Análisis de tiempos de ejecución.
4.3. Ejemplos de aplicación.
4.3.1. Problema de la mochila.
4.3.2. Planificación de tareas.
4.4. Técnicas heurísticas.
4.4.1. El problema del viajante.
4.4.2. Coloración de grafos.
A.E.D. II
Tema 4. Algoritmos voraces.
1
4.1. Método general.
• Los algoritmos voraces, ávidos o de avance rápido (greedy) se
utilizan en problemas de optimización, donde una solución está formada
por un conjunto de elementos entre un conjunto de candidatos (con un
orden determinado o no).
• El algoritmo voraz funciona por pasos. En cada uno se escoge el
siguiente elemento para añadir a la solución. Una vez tomada esta
decisión no se podrá deshacer.
• El algoritmo acabará cuando el conjunto de elementos seleccionados
constituya una solución.
• Ejemplo. Algoritmo de Kruskal, para hallar el árbol de expansión de
costo mínimo.
– El conjunto de candidatos inicial será el conjunto de aristas con sus pesos.
– El elemento seleccionado en cada paso será el candidato de menor coste y
que no forme un ciclo en la solución actual.
– Tenemos una solución cuando hayamos seleccionado N-1 nodos.
• Ejemplo. Algoritmo de Dijkstra, para el cálculo de distancias mínimas.
– Los candidatos son los nodos del grafo.
– Seleccionar en cada paso el nodo candidato con valor de camino especial
A.E.D. II
2
más corto.
Tema 4. Algoritmos voraces.
4.1. Método general.
• Otros ejemplos: algoritmo de Prim, algoritmo para calcular el flujo
máximo.
• ¿Qué pasa con el algoritmo de Floyd?
• Esquema general de un algoritmo voraz:
voraz (C: conjunto_candidatos; var S: conjunto_solución);
S:= Ø;
mientras (C  Ø) y no solución (S) hacer
x:= seleccionar (C);
C:= C - {x};
si factible (S  {x}) entonces
S:= S  {x};
si no solución (S) entonces
devolver “No se puede encontrar una solución”
• En cada paso tenemos los siguientes conjuntos:
– Candidatos seleccionados para la solución S.
– Candidatos seleccionados pero rechazados luego.
– Candidatos pendientes de seleccionar C.
A.E.D. II
Tema 4. Algoritmos voraces.
3
4.1. Método general.
• Funciones:
– solución (S). Comprueba si un conjunto de candidatos es una solución
(independientemente de que sea óptima o no).
– seleccionar (C). Devuelve el elemento más “prometedor” del conjunto de
candidatos restantes, que no han sido seleccionados ni rechazados.
– factible (C). Indica si a partir del conjunto de candidatos C es posible
construir una solución (posiblemente añadiendo otros elementos).
– Insertar un elemento en la solución. Puede ser necesario hacer otras cosas.
– Además, existe una función objetivo (S), que dada una solución devuelve el
coste asociado a la misma (resultado del problema de optimización).
• Para cada uno de los ejemplos de algoritmos voraces ya vistos ¿cómo
están definidas estas funciones?
• Ejemplo. Problema del cambio de monedas.
Disponemos de monedas con valores de 1, 2, 5, 25, 50 y 100 céntimos de euro
(c€). Construir un algoritmo que dada una cantidad P devuelva el cambio con
monedas de estos valores, usando un conjunto mínimo de monedas.
P. ej.: para devolver 2.89 €: 2 monedas de 1 €, 1 moneda de 50 c€,
1 moneda de 25 c€, 1 moneda de 5 c€ y 2 monedas de 2 c€.
A.E.D. II
Tema 4. Algoritmos voraces.
4
4.1. Método general.
• Candidatos iniciales: todos los tipos de monedas disponibles.
Supondremos una cantidad ilimitada de cada una.
• Solución: conjunto de monedas que suman la cantidad P.
• Podemos aplicar la técnica voraz: en cada paso añadir una moneda
nueva a la solución actual, hasta que el valor llegue a P.
• Una solución será de la forma (x1, x2, x3, x4, x5, x6), donde xi es el
número de monedas de tipo i. Suponemos que la moneda i vale ci.
• Funciones:
– solución. El valor actual será solución si  xi·ci = P
– objetivo. La función a minimizar es  xi, el número de monedas
resultante.
– seleccionar. Elegir en cada paso la moneda de valor más alto
posible, pero menor que el valor que queda por devolver.
– factible. Valdrá siempre verdad.
• En lugar de seleccionar monedas de una en una, podemos usar la
división entera y coger todas las monedas posibles de mayor valor.
A.E.D. II
Tema 4. Algoritmos voraces.
5
4.1. Método general.
Devolver-cambio (P: integer; C: array [1..N] of integer; var X: array [1..N] of integer);
act:= 0;
for i:= 1 to N do
X[i]:= 0;
while act  P do begin
j:= el menor elemento de C tal que C[j]  (P - act);
if j=0 then { Si no existe ese elemento }
return “No existe solución”;
X[j]:= (P - act) div C[j];
act:= act + C[j]*X[j];
end;
• ¿Cuál será el orden de complejidad del algoritmo?
• Con el conjunto de monedas dado este algoritmo encuentra siempre
la solución óptimas (el número mínimo de monedas para llegar a P).
• Sin embargo, ¿encuentra siempre la solución óptima?
• Por ejemplo, supongamos que tenemos monedas de 100, 90 y 1.
Queremos devolver 180.
– Algoritmo voraz: 1 moneda de 100 y 80 monedas de 1: total 81 monedas.
– Solución óptima: 2 monedas de 90: total 2 monedas.
A.E.D. II
Tema 4. Algoritmos voraces.
6
4.2. Análisis de tiempos de ejecución.
• El orden de complejidad depende del número de candidatos, de las
funciones básicas a utilizar, del número de elementos de la solución.
• N: número de elementos de C. M: número de elementos de una solución.
• Repetir, como máximo N veces y como mínimo M:
– Comprobar si el valor actual es solución: f(N). Normalmente O(1) ó O(N).
– Selección de un elemento entre los candidatos: g(N). Entre O(1) y O(N).
– La función factible es parecida a solución, pero con una solución parcial
h(N).
– La unión de un nuevo elemento a la solución puede requerir otras
operaciones de cálculo, j(N, M). Por ejemplo, en el algoritmo de Dijkstra
recalcular los caminos especiales mínimos, en O(N).
• Tiempo de ejecución genérico: t(n)  O(N*(f(N)+g(N)+h(N))+M*j(N, M))
• Ejemplos:
– Algoritmos de Dijkstra, Prim y Kruskal: se ordenan los candidatos y se
escogen de forma ordenada: O(a·log n).
– Devolución de monedas: podemos encontrar el siguiente elemento en un
tiempo constante (ordenando las monedas): O(N).
• En la práctica los algoritmos voraces suelen ser bastante rápidos,
encontrándose dentro de órdenes de complejidad polinomiales.
A.E.D. II
Tema 4. Algoritmos voraces.
7
4.3. Ejemplos de aplicación.
4.3.1. Problema de la mochila.
20 Kg.
• Tenemos n objetos, cada uno con un peso (wi) y un beneficio (vi).
También tenemos una mochila en la que podemos meter objetos, con
una capacidad de peso máximo M. (Supondremos todos los valores > 0)
• El objetivo es llenar la mochila, maximizando el valor de los objetos
transportados, y respetando la limitación de capacidad máxima M.
• Supondremos que los objetos se pueden partir. De cada objeto i
podremos coger un fracción xi, entre 0 y 1.
• Una solución será de la forma S = (x1, x2, ..., xn), cumpliendo:
n
R e s tric c ió n

n
xi  wi  M
F u n c ió n o b je tivo
i 1

xi  vi
i 1
A.E.D. II
Tema 4. Algoritmos voraces.
8
4.3.1. Problema de la mochila.
• Ejemplo: n = 3; M = 20
w = (18, 15, 10)
v = (25, 24, 15)
Solución 1: S = (1, 2/15, 0), Valor total = 25 + 24*2/15 = 28.2
Solución 2: S = (0, 2/3, 1), Valor total = 15 + 24*2/3 = 31
• Diseño de la solución. Podemos utilizar un algoritmo voraz para
resolver el problema.
– Candidatos: Cada uno de los n objetos de partida.
– Función solución: Tendremos una solución si hemos introducido en la
mochila el peso máximo M (o si se han acabado los objetos).
– Función seleccionar: Escoger el objeto más prometedor.
– Función factible: Será siempre cierta (podemos añadir trozos de objetos).
– Añadir a la solución: Añadir el objeto entero si cabe en la mochila, o en otro
caso la proporción del mismo que quede para completarla.
– Función objetivo: Suma de los beneficios de cada candidato por la
proporción seleccionada del mismo.
• Queda por definir la función de selección. ¿Qué criterio podemos usar
para elegir el objeto más prometedor? ¿Garantiza una solución óptima?
A.E.D. II
Tema 4. Algoritmos voraces.
9
4.3.1. Problema de la mochila.
Mochila (M: integer; V, W: array [1..N] of integer; var X: array [1..N] of integer);
for i:= 1 to N do
X[i]:= 0;
peso_act:= 0;
while peso_act < M do begin
j:= el mejor objeto restante;
if peso_act + W[i]  M then begin
X[i]:= 1;
peso_act:= peso_act + W[i];
end
else begin
X[i]:= (M - peso_act)/W[i];
peso_act:= M;
end;
end;
• Criterios para seleccionar el mejor objeto de los restantes:
1. El objeto con más beneficio vi.
2. El objeto menos pesado wi (para poder añadir muchos objetos).
3. El objeto con mejor proporción vi/wi (coste por unidad de peso).
A.E.D. II
Tema 4. Algoritmos voraces.
10
4.3.1. Problema de la mochila.
• Ejemplos: n = 4; M = 10
w = (10, 3, 3, 4)
v = (10, 9, 9, 9)
Criterio 1: S = (1, 0, 0, 0). Valor total = 10
Criterio 2 y 3: S = (0, 1, 1, 1). Valor total = 27
w = (10, 3, 3, 4)
v = (10, 1, 1, 1)
Criterio 1 y 3: S = (1, 0, 0, 0). Valor total = 10
Criterio 2: S = (0, 1, 1, 1). Valor total = 3
• Los criterios 1 y 2 pueden dar soluciones no muy buenas.
• El criterio 3 garantiza siempre una solución óptima.
• Demostración (por reducción al absurdo): Supongamos que tenemos una
•
solución óptima, que incluye un objeto i, pero no incluye (o incluye con menor
proporción x) otro objeto j con mejor proporción: (xi > xj) y (vi/wi < vj/wj).
Si quitamos un trozo de peso de i y lo metemos de j entonces obtendríamos más
beneficio. Por ejemplo, si quitamos un peso p, con 0 < p  xi·wi , p  (1-xj)·wj:
vNUEVO = vANTIGUO - p*vi/wi + p*vj/wj = vANTIGUO + p*(vj/wj - vi/wi) > vANTIGUO
A.E.D. II
Tema 4. Algoritmos voraces.
11
4.3.2. Planificación de tareas.
Minimización del tiempo en el sistema
• Tenemos un único procesador, que debe ejecutar n tareas, de forma
secuencial.
• Para cada tarea i conocemos de antemano el tiempo que tardará en
ejecutarse ti. Suponemos que todas las tareas están disponibles en el
instante inicial.
• El objetivo es dar un orden de ejecución de las tareas, de forma que el
tiempo medio de finalización de las tareas sea mínimo  el tiempo total
de finalización de las tareas debe ser mínimo.
•
Ejemplo. Supongamos que tenemos 3 tareas con: t1= 4, t2=8, t3= 2
1
2
1
3
3
1
2
3
T=
0
3
1
3
3
1
1
8
T T O T A L = 8 + 1 2+ 1 4 = 3 4
T T O T A L = 8 + 1 0+ 1 4 = 3 2
T T O T A L = 2 + 6+ 1 4 = 2 2
2
2
4
T T O T A L = 4 + 6+ 1 4 = 2 4
2
2
T T O T A L = 4 + 1 2+ 1 4 = 3 0
T T O T A L = 2 + 1 0+ 1 4 = 2 6
1 2 14
A.E.D. II
Tema 4. Algoritmos voraces.
12
4.3.2. Planificación de tareas.
• Podemos aplicar la técnica de avance rápido:
– Los candidatos son las n tareas.
– La solución no es un conjunto de candidatos, sino el orden en que deben
ejecutarse.
– Añadir un nuevo candidato no es una unión de conjuntos sino insertar un
nuevo elemento a una lista.
– Función de selección: ejecutar primero la tarea más corta de entre los
candidatos restantes.
• Solución del problema de planificación: ordenar las tareas en orden
creciente de duración (ti).
• ¿Garantiza este método la solución óptima?
• Demostración: Supongamos que tenemos una ordenación S= (i1, i2, ..., in),
con tiempos (t1, t2, ..., tn), entonces el tiempo hasta que se finaliza la tarea i
será:
Ti = t1 + t2 + ... + ti
El tiempo total de espera de los procesos será:
TTOTAL = t1 + (t1+t2) + (t1+t2+t3) + ... + (t1+t2+ ... + tn) = n·t1 + (n-1)·t2 +...+ tn =
n

 ( n  i  1)  t
i 1
i
A.E.D. II
Tema 4. Algoritmos voraces.
13
4.3.2. Planificación de tareas.
• Por reducción al absurdo, si S=(t1, t2, ..., tn) no están ordenados de forma
creciente entonces podemos seleccionar un i, j, tal que (i<j) y (ti>tj). Si los
intercambiamos en el orden S entonces el nuevo tiempo total disminuye:
TTOTAL = T’TOTAL- (n-i+1)ti - (n-j+1)tj + (n-i+1)tj + (n-j+1)ti = T’TOTAL + (i-j)ti + (j-i)tj =
= T’TOTAL + (i-j)(ti - tj) < T’TOTAL
{Pues (i-j) < 0
y
(ti - tj) > 0}
• Conclusión: La solución óptima se obtiene ordenando las tareas en
orden creciente de duración. El algoritmo voraz es una simple
ordenación, que se puede ejecutar en (n·log n).
Planificación con plazo fijo
• En la planificación con plazo fijo suponemos que todas las n tareas
requieren un tiempo unitario en ejecutarse.
• En cualquier instante T = 1, 2, ... podemos ejecutar una única tarea i. La
ejecución de esta tarea provocará un beneficio gi.
• Restricción: una tarea i sólo puede ejecutarse si se hace antes de un
plazo di. Cada tarea tiene un plazo de ejecución y un beneficio dados.
• En general puede que no sea posible ejecutar todas las tareas.
A.E.D. II
Tema 4. Algoritmos voraces.
14
4.3.2. Planificación de tareas.
• Objetivo: dar una planificación de las tareas a ejecutar (i1, i2, ..., im) de
m
forma que se maximice el beneficio obtenido:  k 1 g i k
• Ejemplo: n = 4
g = (100, 10, 15, 27)
d = ( 2, 1, 2, 1)
Soluciones:
(1)
GTOTAL = 100
(4, 3) GTOTAL = 42
(4, 1)
(2, 1) GTOTAL = 110
GTOTAL = 127
• Comprobar todas las posibilidades tendría una complejidad n!
• Con un algoritmo voraz construimos la solución paso a paso.
• Una solución estará formada por un conjunto de candidatos, junto con
un orden de ejecución de los mismos, S = (i1, i2, ..., im).
• Función solución: Tendremos la solución cuando hayamos tratado
todos los candidatos.
• Función de selección: de los candidatos restantes elegir el que tenga
mayor valor de beneficio.
A.E.D. II
Tema 4. Algoritmos voraces.
15
4.3.2. Planificación de tareas.
• Función factible: Dada una planificación (i1, i2, ..., ik) en un paso del
algoritmo y un nuevo candidato j,
– ¿Cuándo será factible la solución parcial que incluye a j?
– ¿Dónde debería ser colocado j dentro de la planificación?
• Solución: buscar si existe alguna ordenación de {i1, i2, ..., ik, j} que
respete los plazos de ejecución di. Problema: complejidad (k+1)!
• Parece lógico no comprobar todas las posibles ordenaciones, sino
hacer una ordenación de forma que las tareas con plazos di más
tempranos se ejecuten antes, y dejar para después las que tengan
plazos mayores.
• Lema: Sea J un conjunto de k tareas, entonces existe una ordenación
factible de J (es decir que respeta los plazos) si y sólo si la ordenación
S = (s1, s2, ..., sk), con ds1  ds2  ...  dsk es factible.
• Es decir, sólo es necesario probar la planificación en orden creciente
de plazo de ejecución, comprobando si cada dsi  i (la tarea ejecutada
en la i-ésima posición tiene un plazo de i ó más).
A.E.D. II
Tema 4. Algoritmos voraces.
16
4.3.2. Planificación de tareas.
• Demostración del lema:
– Si el orden S es factible entonces existe una ordenación factible de J: Trivial.
– Si existe una ordenación factible de J entonces S es factible:
Supongamos (reducción al absurdo) que existe esa ordenación pero que S
(definida de la forma anterior) no es factible.
Entonces debe existir una tarea sr tal que dsr < r. Puesto que las r-1 tareas
anteriores tienen dsi  dsr < r, habrán r tareas cuyo plazo sea menor que r.
En conclusión, no puede existir ningún orden de las tareas J, de forma que
se ejecuten dentro de su plazo.
• Estructura del algoritmo voraz:
– Empezar con una secuencia vacía, con todos las tareas como candidatas.
– Ordenar los candidatos según el valor de gi.
– En cada paso, hasta que se acaben los candidatos, repetir:
• Elegir entre los candidatos restantes el que tenga mayor beneficio.
• Comprobar si es posible añadir la tarea elegida a la solución actual. Para
ello introducir la nueva tarea en la posición adecuada, según el valor de
plazo d.
• Si el nuevo orden (s1, s2, ..., sk) es tal que dsi  i, para todo i entre 1 y k,
entonces el nuevo candidato es factible. Sino rechazar el candidato.
A.E.D. II
Tema 4. Algoritmos voraces.
17
4.3.2. Planificación de tareas.
• Ejemplo: n=6
g = (20, 15, 10, 7, 5, 3)
d = ( 3, 1, 1, 3, 1, 3)
• Es posible demostrar que este algoritmo obtiene la solución óptima.
Idea: suponer una solución óptima y comprobar que tiene el mismo
beneficio que la calculada por el algoritmo.
• Orden de complejidad del algoritmo, suponiendo n tareas:
– Primero, ordenar las tareas por orden creciente de plazo: O(n·log n)
– Repetir para i desde 1 hasta n:
• Elegir el próximo candidato: O(1).
• Comprobar si la nueva planificación es factible, y añadirlo a la solución
en caso afirmativo: O(i) en el peor caso.
– En total, el algoritmo es de O(n2).
A.E.D. II
Tema 4. Algoritmos voraces.
18
4.4. Técnicas heurísticas.
• Existen muchos problemas para los cuales no existe un algoritmo que
pueda encontrar la solución de forma eficiente.
• La solución exacta puede requerir un orden factorial o exponencial: el
problema de la explosión combinatoria.
• En estos casos puede ser necesario utilizar algoritmos heurísticos.
• Un algoritmo heurístico (o simplemente heurística) es un
procedimiento que puede producir una buena solución para el problema
(puede que la óptima) pero también puede que no produzca ninguna
solución o dar lugar a una solución no muy buena.
• Normalmente, la heurística se basa en algún conocimiento intuitivo del
programador sobre un determinado problema, en algo que suele
funcionar bien (aunque no está garantizado en todos los casos).
• La estructura de algoritmo voraz se puede utilizar para construir
procedimientos heurísticos: hablamos de heurísticas voraces.
• Objetivo: obtener buenas soluciones en un tiempo de ejecución corto.
• Ejemplo: el algoritmo para el cambio de monedas es una heurística
voraz, pues no garantiza la solución óptima en todos los casos.
A.E.D. II
Tema 4. Algoritmos voraces.
19
4.4. Técnicas heurísticas.
4.4.1. El problema del viajante.
• Problema: Dado un grafo no dirigido, completo y ponderado G = (V, A),
encontrar un ciclo simple de costo mínimo que pase por todos los nodos.
10
2
45
40
25
1
55
5
20
4
30
35
50
3
15
• Es un problema NP, pero necesitamos una solución eficiente.
• Problema de optimización, donde la solución está formada por un grupo
de elementos en cierto orden: podemos aplicar el esquema voraz.
• Posibilidades:
1) Los nodos son los candidatos. Empezar en un nodo cualquiera. En cada
paso moverse al nodo no visitado más próximo al último nodo seleccionado.
2) Las aristas son los candidatos. Hacer igual que en el algoritmo de Kruskal,
pero garantizando que se forme un ciclo.
A.E.D. II
Tema 4. Algoritmos voraces.
20
4.4.1. El problema del viajante.
• Heurística voraz 1)
•
– Una solución será un cierto orden en el conjunto de nodos (c1, c2, ..., cn), el
orden de visita de los nodos.
– Inicialización: seleccionar un nodo cualquiera.
– Función de selección: de los nodos candidatos seleccionar el más próximo
al último (o al primero) de la secuencia actual (c1, c2, ..., ca).
– Acabamos cuando tengamos n nodos.
10
Ejemplo.
2
3
45
Empezando en el nodo 1.
25
30
1
4
Solución: (1, 4, 5, 3, 2)
Coste: 30+15+25+10+45=125
2
Empezando en el nodo 3.
Solución: (5, 4, 3, 2, 1)
Coste: 15+20+10+45+50=140
15
5
10
3
45
20
1
4
50
A.E.D. II
Tema 4. Algoritmos voraces.
5
15
21
4.4.1. El problema del viajante.
• Heurística voraz 2)
•
– Una solución será un conjunto de aristas (a1, a2, ..., an-1) que formen un ciclo
hamiltoniano, sin importar el orden.
– Empezar con un grafo sin aristas.
– Selección: seleccionar en cada paso la arista candidata de menor coste.
– Factible: una arista se puede añadir a la solución actual si no se forma un
ciclo (excepto para la última arista añadida) y si los nodos unidos no tienen
grado mayor que 2.
10
2
3
Ejemplo.
45
20
Solución: ((2, 3), (4, 5), (3, 4), (1, 2), (1, 5))
1
Coste = 10+15+20+45+50 = 140
4
50
• Conclusiones:
5
15
– Ninguno de los dos algoritmos garantiza una solución óptima. Sin embargo,
normalmente ambos dan soluciones buenas, próximas a la óptima.
– Posibles mejoras: buscar heurísticas mejores; repetir la heurística 1 con
varios orígenes; ó bien, a partir de la solución del algoritmo intentar hacer
modificaciones locales para mejorar esa solución.
A.E.D. II
Tema 4. Algoritmos voraces.
22
4.4.2. Coloración de grafos.
• Problema: dado un grafo no dirigido, realizar una coloración utilizando el
número mínimo de colores.
• Coloración: asignación de un color a cada nodo, de forma que dos
nodos unidos con un arco tengan siempre distinto color.
4
1
3
2
5
• Una solución será un conjunto de pares de la forma (nodo, color)
cumpliendo que para todo (ni, ci) y (nj, cj), si (ni, nj) es una arista del grafo,
entonces ci  cj.
• Podemos usar una heurística voraz para obtener una solución:
– Empezar con un color c1, y todos los nodos sin colorear.
– Para cada uno de los nodos que no tienen asignado un color, comprobar si es
posible asignarles el color actual. Repetir hasta comprobar todos los
candidatos.
– Si quedan nodos sin colorear, escoger otro color y volver al paso anterior.
A.E.D. II
Tema 4. Algoritmos voraces.
23
4.4.2. Coloración de grafos.
• Ejemplo.
4
Solución: ((1, 1), (2, 1), (3, 2),
(4, 3), (5, 3))
Número de colores = 3
3
1
2
5
• La estructura básica del esquema voraz se repite varias veces, una por
cada color, hasta que todos los nodos estén coloreados.
• Función de selección: seleccionar cualquier candidato restante.
• Función factible: se puede asignar un color al candidato actual si
ninguno de sus adyacentes tiene ese mismo color.
• El algoritmo no garantiza la solución óptima (en el ejemplo 2 colores).
4
1
3
2
5
• ¿Cuál será el tiempo de ejecución en el peor caso?
A.E.D. II
Tema 4. Algoritmos voraces.
24
Descargar