Algoritmos greedy
Un algoritmo voraz (también conocido como ávido,
devorador o goloso) es aquel que, para resolver un
determinado problema, sigue una heurística
consistente en elegir la opción óptima en cada paso
local con la esperanza de llegar a una solución
general óptima. Este esquema algorítmico es el que
menos dificultades plantea a la hora de diseñar y
comprobar su funcionamiento. Normalmente se
aplica a los problemas de optimización.
Dado un conjunto finito de entradas C, un algoritmo voraz devuelve un conjunto S (seleccionados) tal que S ⊆ C y que además cumple con las restricciones del problema inicial.
Cada conjunto 𝑆 que satisfaga las restricciones se le suele denominar prometedor, y si este además logra que la función objetivo se minimice o maximice (según corresponda) diremos que 𝑆 es una solución óptima
Para ello trabajará por etapas, tomando en cada una de ellas la decisión que le parece la mejor, sin considerar las consecuencias futuras, y por tanto escogerá de entre todos los candidatos el que produce un óptimo local para esa etapa, suponiendo que será a su vez óptimo global para el problema.
Antes de añadir un candidato a la solución que está construyendo comprobará si es prometedora al añadirlo. En caso afirmativo lo incluirá en ella y en caso contrario descartará este candidato para siempre y no volverá a considerarlo.
Cada vez que se incluye un candidato comprobará si el conjunto obtenido es solución
Candidato: conjunto finito de monedas de, por ejemplo, 1, 5, 10 y 25 unidades, con un número de monedas ilimitado o limitado.
Solución: conjunto de monedas cuya suma es la cantidad a pagar.
Prometedor: 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.
La estrategia a seguir consiste en escoger sucesivamente las monedas de valor mayor que no superen la cantidad de cambio a devolver. El buen funcionamiento del algoritmo depende de los tipos de monedas presentes en la entrada. Así, por ejemplo, si no hay monedas de valor menor que diez, no se podrá devolver un cambio menor que diez. Además, la limitación del número de monedas también influye en la optimalidad del algoritmo, el cual devuelve buenas soluciones bajo determinados conjuntos de datos, pero no siempre.
Si hay que devolver la cantidad 110, se tomaría primero una moneda de 50, quedando una cantidad restante de 60. Como 50 es aún menor que 60, se tomaría otra moneda de 50. Ahora la cantidad restante es 10, por tanto ya tenemos que devolver una moneda de 5, ya que 50 y 25 son mayores que 10, y por tanto se desechan. La cantidad a devolver ahora es 5. Se tomaría otra moneda de 5, terminando así el problema de forma correcta.
Solución: Devolver dos monedas de 50 y dos de 5.
Si consideramos además un numero de monedas de cada denominación no ilimitado deberemos ahora de considerar que sea posible tomar monedas de cada denominación para formar la solución
Si hay que devolver la cantidad 110 siguiendo el método del algoritmo voraz, se tomaría primero una moneda de 50, quedando una cantidad restante de 60. Como 50 es aún menor que 60, se tomaría otra moneda de 50. Ahora la cantidad restante es 10, por tanto ya tenemos que devolver una moneda de 5, ya que 50 y 25 son mayores que 10, y por tanto se desechan. La cantidad a devolver ahora es 5. Se tomaría otra moneda de 5, pero puesto que ya no nos queda ninguna, deberán devolverse 5 de valor 1, terminando así el problema de forma correcta
Solución: Devolver dos monedas de 50, una de 5 y cinco de 1.
Dado un conjunto finito de entradas C, un algoritmo voraz devuelve un conjunto S (seleccionados) tal que S ⊆ C y que además cumple con las restricciones del problema inicial.
Cada conjunto 𝑆 que satisfaga las restricciones se le suele denominar prometedor, y si este además logra que la función objetivo se minimice o maximice (según corresponda) diremos que 𝑆 es una solución óptima
Elementos de los que consta la técnica
El conjunto 𝑪 de candidatos, entradas del problema.
Función solución, esta comprueba, en cada paso, si el
subconjunto actual de candidatos elegidos forma una
solución (no importa si es óptima o no lo es).
Función de selección, informa de cuál es el elemento más
prometedor para completar la solución. Éste no puede haber
sido escogido con anterioridad. Cada elemento es
considerado una sola vez. Luego, puede ser rechazado o
aceptado y pertenecerá a 𝐶 \ 𝑆.
Función de factibilidad, informa si a partir de un conjunto se
puede llegar a una solución. Lo aplicaremos al conjunto de
seleccionados unido con el elemento más prometedor.
Función objetivo, es aquella que queremos maximizar o
minimizar, el núcleo del problema.
Forma general de un algoritmo ávido
Para identificar si un problema es susceptible de ser
resuelto por un algoritmo ávido se definen una serie
de elementos que han de estar presentes en el
problema:
- Un conjunto de candidatos, que corresponden a las n entradas del problema.
- Una función de selección que en cada momento determine el candidato idóneo para formar la solución de entre los que aún no han sido seleccionados ni rechazados.
- Una función que compruebe si un cierto subconjunto de candidatos es prometedor. Entendemos por prometedor que sea posible seguir añadiendo candidatos y encontrar una solución
- Una función objetivo que determine el valor de la solución hallada. Es la función que queremos maximizar o minimizar.
- Una función que compruebe si un subconjunto de estas entradas es solución al problema, sea óptima o no.
Planteamiento de un algoritmo ávido
Para resolver el problema, un algoritmo ávido tratará de encontrar un subconjunto de candidatos tales que, cumpliendo las restricciones del problema, constituya la solución óptima.Para ello trabajará por etapas, tomando en cada una de ellas la decisión que le parece la mejor, sin considerar las consecuencias futuras, y por tanto escogerá de entre todos los candidatos el que produce un óptimo local para esa etapa, suponiendo que será a su vez óptimo global para el problema.
Antes de añadir un candidato a la solución que está construyendo comprobará si es prometedora al añadirlo. En caso afirmativo lo incluirá en ella y en caso contrario descartará este candidato para siempre y no volverá a considerarlo.
Cada vez que se incluye un candidato comprobará si el conjunto obtenido es solución
Ejemplo. Mínimo número de monedas
Se pide crear un algoritmo que permita a una máquina expendedora devolver el cambio mediante el menor número de monedas posible.- Considerando que el número de monedas es ilimitado.
- Considerando que el número de monedas es limitado, es decir, se tiene un número concreto de monedas de cada tipo.
Candidato: conjunto finito de monedas de, por ejemplo, 1, 5, 10 y 25 unidades, con un número de monedas ilimitado o limitado.
Solución: conjunto de monedas cuya suma es la cantidad a pagar.
Prometedor: 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.
La estrategia a seguir consiste en escoger sucesivamente las monedas de valor mayor que no superen la cantidad de cambio a devolver. El buen funcionamiento del algoritmo depende de los tipos de monedas presentes en la entrada. Así, por ejemplo, si no hay monedas de valor menor que diez, no se podrá devolver un cambio menor que diez. Además, la limitación del número de monedas también influye en la optimalidad del algoritmo, el cual devuelve buenas soluciones bajo determinados conjuntos de datos, pero no siempre.
Si hay que devolver la cantidad 110, se tomaría primero una moneda de 50, quedando una cantidad restante de 60. Como 50 es aún menor que 60, se tomaría otra moneda de 50. Ahora la cantidad restante es 10, por tanto ya tenemos que devolver una moneda de 5, ya que 50 y 25 son mayores que 10, y por tanto se desechan. La cantidad a devolver ahora es 5. Se tomaría otra moneda de 5, terminando así el problema de forma correcta.
Solución: Devolver dos monedas de 50 y dos de 5.
Si consideramos además un numero de monedas de cada denominación no ilimitado deberemos ahora de considerar que sea posible tomar monedas de cada denominación para formar la solución
Si hay que devolver la cantidad 110 siguiendo el método del algoritmo voraz, se tomaría primero una moneda de 50, quedando una cantidad restante de 60. Como 50 es aún menor que 60, se tomaría otra moneda de 50. Ahora la cantidad restante es 10, por tanto ya tenemos que devolver una moneda de 5, ya que 50 y 25 son mayores que 10, y por tanto se desechan. La cantidad a devolver ahora es 5. Se tomaría otra moneda de 5, pero puesto que ya no nos queda ninguna, deberán devolverse 5 de valor 1, terminando así el problema de forma correcta
Solución: Devolver dos monedas de 50, una de 5 y cinco de 1.
Ejemplo. Algoritmos greedy sobre grafos
Árboles generadores minimales
Problema
Dado un grafo conexo G = (V, A) no dirigido y ponderado con pesos
positivos, calcular un subgrafo conexo T ⊆ G que conecte todos los
vértices del grafo G y que la suma de los pesos de las aristas seleccionadas
sea mínima.
Solución
Este subgrafo es necesariamente un árbol: árbol generador minimal o
árbol de recubrimiento mínimo (“minimum spanning tree” [MST]).Aplicaciones
- Diseño de redes: redes telefónicas, eléctricas, hidráulicas, de ordenadores, de carreteras…
- Construcción de redes de mínimo coste
- Refuerzo de líneas criticas
- Identificación de cuellos de botella
- Enrutamiento (evitar ciclos)
- Soluciones aproximadas para problemas NP.
- Algoritmos de agrupamiento (análisis de clúster)
Algoritmos Greedy para resolver el problema:
Algoritmo de Kruskal:
Comenzando con T=∅, considerar las aristas en orden creciente de coste y
añadir las aristas a T salvo que hacerlo suponga la creación de un ciclo
Algoritmo de Prim:
Comenzando con un nodo raíz arbitrario s, hacer crecer el árbol T desde s
hacia afuera. En cada paso, se añade al árbol T el nodo que tenga una
arista de menor coste que lo conecte a otros nodos de T.
Algoritmo de borrado inverso:
Comenzando con T=A, considerar las aristas en orden decreciente de coste
y eliminar las aristas de T salvo que eso desconectase T.
Ejemplo. Caminos mínimos
Algoritmo de Dijkstra (1959)
El algoritmo de Djikstra es un algoritmo muy único. Inicialmente, se
utiliza un enfoque voraz para conseguir distancias iniciales a los nodos
vecinos. Luego, en el siguiente paso, se comprueba si el valor
calculado es el óptimo global a ese nodo o no. Si no, se comprueba
todos los otros caminos y calcula la distancia óptima a ese
nodo. Luego, basándose en los valores ya calculados de los nodos
anteriores, se calcula el camino más corto para el nodo final. Por lo
tanto, esto es una especie de un enfoque de programación dinámica
Así, Djikstra utiliza ambos enfoques y, por tanto, no puede ser
completamente clasificada como "Greedy" o "DP". Es una mezcla de
ambos y por lo tanto, es único. Siempre ha sido un tema debatido. Tal
es la belleza del algoritmo.
Dado un grafo G=(V,A) y un vértice s, encontrar el camino de costo
mínimo para llegar desde s al resto de los vértices en el grafo.
IDEA: Mantener el conjunto de nodos ya explorados para los cuales ya
hemos determinado el camino más corto desde s…
Comentarios
Publicar un comentario