Algoritmos+Voraces

=Introducción a los Algoritmos Ávidos=

Se usan para **optimizar** o **minimizar** una función objetivo partiendo de un conjunto de entradas. Esta estrategia de solución consiste en ir seleccionando los elementos que conformaran (en su conjunto) una solución óptima global del problema. Debemos contar con una función local de selección que nos asegure una solución óptima global (en el mejor de los casos). Una vez seleccionado el candidato, no hay marcha atrás, de ahí la importancia de la función de la selección local.

Planteamiento
Dado un problema con n entradas el método consiste en obtener un subconjunto de éstas que satisfaga una determinada restricción definida por el problema.

Cada uno de los conjuntos que cumplan con estás restricciones, los llamaremos prometedores.

¿cómo distinguir un problema en donde aplicar este enfoque?
Serie de elementos que deben estár presente en el problema:


 * Un conjunto de //cadidatos// (n entradas).
 * Una //función de selección// que en cada momento identifique el candidato idóneo para formar la solución.
 * Una función que compruebe si cierto subconjunto de candidatos es //prometedor//, es decir, 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 debemos maximizar o minimizar.
 * Otra función que compruebe si un subconjunto de estas entradas es //solución// al problema, sea óptimo o no.

¿Cómo funciona el algoritmo?

 * 1) El algoritmo tratará de encontrar un subconjunto de candidatos que cumplan las restricciones del problema y constituyan una solución óptima.
 * 2) Esto lo realiza por etapas, tomando en cada una de ellas la decisión que le parece mejor, sin considerar las consecuencias futuras, es decir, elegirá un óptimo local. Aunque con esto no se aseguré que formará parte de la solución global.
 * 3) Antes de añadir un candidato a la solución que se va construyendo, comprobará si al hacerlo la solución se vuelve prometedora. En caso de que lo sea se incluirá en la solución, si no es así el candidato es descartado y marcado (para no volver a considerarlo).
 * 4) Cada vez que se incluye un candidato comprabará si el conjunto obtenido es solución.

Resumen //Los algoritmos ávidos construyen la solución en etapas sucesivas, tratando siempre de tomar la decisión óptima para cada etapa.//

Ejemplo. Dado una cantidad **n** conjunto de monedas (con los valores **200, 100, 50, 25, 10, 5 y 1**), encontrar el número de monedas de cada denominación que se necesitan para representar dicha cantidad de entrada.

Implementación de la solución con un esquema ávido en C++. code format="cpp" main{ int monedas[N] = {200,100,50,25,10,5,1},   //entrada de N elementos cambio[N];   //vector solución int i,j,n ; while (scanf ("%d\n",&n) && n){ printf ("%d = ",n); //inicialización for (j=0; j<N; j++) cambio[j]=0; //función objetivo: minimizar el número de monedas for (i =0 ; i< N; i++) //óptimo local: Ci mejor que Ci+1 while (monedas[i] <= n)               cambio[i]++, n=n-monedas[i];
 * 1) include
 * 2) define N 7

for (j=0; j<N; j++) printf ("%d(%d)",cambio[j],monedas[j]), printf ("%s", j+1<N ? " + ": "\n");

} } code

Sample Input code 343 123 23 3 1233 344393 2341123 93003 314 4555 111 344 203 0

code Sample Output code 343 = 1(200) + 1(100) + 0(50) + 1(25) + 1(10) + 1(5) + 3(1) 123 = 0(200) + 1(100) + 0(50) + 0(25) + 2(10) + 0(5) + 3(1) 23 = 0(200) + 0(100) + 0(50) + 0(25) + 2(10) + 0(5) + 3(1) 3 = 0(200) + 0(100) + 0(50) + 0(25) + 0(10) + 0(5) + 3(1) 1233 = 6(200) + 0(100) + 0(50) + 1(25) + 0(10) + 1(5) + 3(1) 344393 = 1721(200) + 1(100) + 1(50) + 1(25) + 1(10) + 1(5) + 3(1) 2341123 = 11705(200) + 1(100) + 0(50) + 0(25) + 2(10) + 0(5) + 3(1) 93003 = 465(200) + 0(100) + 0(50) + 0(25) + 0(10) + 0(5) + 3(1) 314 = 1(200) + 1(100) + 0(50) + 0(25) + 1(10) + 0(5) + 4(1) 4555 = 22(200) + 1(100) + 1(50) + 0(25) + 0(10) + 1(5) + 0(1) 111 = 0(200) + 1(100) + 0(50) + 0(25) + 1(10) + 0(5) + 1(1) 344 = 1(200) + 1(100) + 0(50) + 1(25) + 1(10) + 1(5) + 4(1) 203 = 1(200) + 0(100) + 0(50) + 0(25) + 0(10) + 0(5) + 3(1)

code