You are on page 1of 12

ALGORITMO DE GREEDY

Cruzado Berr Luis


Paredes Quispe Angelic

INTRODUCCION
El mtodo Greedy es generalmente utilizado para resolver problemas de optimizacin,
es decir, problemas en los cuales se tiene un conjunto de candidatos, de los cuales se
debe elegir un subconjunto que satisfaga una cierta condicin de optimalizad y
eventualmente condiciones de factibilidad.
El mtodo Greedy consiste en analizar el conjunto de candidatos y tomar, en cada
etapa una decisin optima (elegir el mejor candidato). Esta decisin es tomada
localmente, sea sin tener en cuenta las decisiones de etapas pasadas o de etapas
futuras.
De acuerdo a lo anterior se puede resumir que el mtodo Greedy trabaja en etapas y
en cada etapa se toma una decisin localmente optima, de manera de generar la
solucin ptima al problema.
Claramente el hecho de generar la solucin optima a partir de una sucesin de
decisiones localmente optimas en varias etapas, no es vlido para cualquier problema
ni aun para instancias del mismo problema.

CARACTERSTICAS GENERALES.

Se utilizan generalmente para resolver problemas de optimizacin


(obtener el mximo o el mnimo).
Toman decisiones en funcin de la informacin que est disponible
en cada momento.
Suelen ser rpidos y fciles de implementar.
No siempre garantizan alcanzar la solucin ptima.
IMPORTANTE
EL ENFOQUE GREEDY NO NOS GARANTIZA OBTENER SOLUCIONES PTIMAS.

Para poder resolver un problema usando el enfoque Greedy, tendremos


que considerar 6 elementos:

1) Conjunto de candidatos (elementos seleccionables)


2) Solucin parcial (candidatos seleccionados).
3) Funcin de seleccin (determina el mejor candidato del conjunto de
candidatos seleccionables).
4) Funcin de factibilidad (determina si es posible completar la
solucin parcial para alcanzar una solucin del problema).
5) Criterio que define lo que es una solucin (indica si la solucin
parcial obtenida resuelve el problema).
6) Funcin objetivo (valor de la solucin alcanzada).

ESQUEMA GENERAL.

Ejemplo 1 (problema de las monedas)


Dada una cantidad de dinero y un conjunto de monedas de distintos valores, cambiar a
monedas el dinero utilizando la mnima cantidad de monedas.
Se plantea el siguiente algoritmo para resolver el problema:
Mientras dinero > 0 hacer
Sea i la moneda de mayor valor que cumple
valor (i) <= dinero entonces

K: = dinero div valor (i)


dinero = dinero - k * valor (i)
Se puede observar que es un algoritmo basado en el mtodo Greedy, trabaja por etapas y
toma en cada una de ellas la decisin localmente ptima: tomar tantas veces como sea posible
la moneda de mayor valor.
A continuacin se ver que sucede para distintas instancias del problema:
a) Dinero = 10
Monedas con valores 3 y 2
No se puede resolver con el algoritmo planteado, aunque existe una solucin al
problema.

b) Dinero = 15
Monedas con valores 11, 5 y 1
El resultado que se obtenido usando el algoritmo planteado:
1 moneda de 11
4 monedas de 1
Por lo tanto aunque el algoritmo halla una solucin al problema, esta no es ptima dado que la
solucin ptima est dada por 3 monedas de 5.
c) Dinero = 15
Monedas con valores 10, 5 y 1
El resultado que se obtiene usando el algoritmo planteado:
1 moneda de 10
1 moneda de 5
Lo cual constituye la solucin ptima.
Como conclusin puede decirse que este problema no es resoluble por el mtodo Greedy,
dado que hallar la solucin optima tomando la moneda de mayor valor (decisin localmente
optima) en cada etapa conduce a la solucin optima dependiendo del valor delas monedas.

Problema de la Mochila en Programacin Entera resuelto


El Problema de la Mochila (conocido tambin como Knapsack Problem o simplemente KP) es
un problema clsico de la Investigacin de Operaciones y en particular de la Programacin
Entera. Consiste en un excursionista que debe preparar su mochila, la cual tiene una capacidad
limitada y por tanto no le permite llevar todos los artculos que quisiera tener en la excursin.

Cada artculo que el excursionista puede incluir en la mochila le reporta una determinada
utilidad. Luego el problema consiste en seleccionar un subconjunto de objetos de forma tal
que se maximice la utilidad que el excursionista obtiene, pero sin sobrepasar la capacidad de
acarrear objetos.

En este contexto existen varias aplicaciones que guardan una similitud conceptual con el
Problema de la Mochila y en consecuencia nos podemos beneficiar de la formulacin y
resolucin de un modelo de optimizacin matemtica para dicho propsito. Consideremos el
siguiente ejemplo:

Problema de la Mochila
Un armador tiene un carguero con capacidad de hasta 700 toneladas. El carguero transporta
contenedores de diferentes pesos para una determinada ruta. En la ruta actual el carguero
puede transportar algunos de los siguientes contenedores:

El analista de la empresa del armador desea determinar el envo (conjunto de contenedores)


que maximiza la carga transportada. Para ello se propone el siguiente modelo de

Programacin Entera:
Variables de Decisin:

Funcin Objetivo: Consiste en maximizar la carga que transportar el carguero.

Restricciones: El peso de la carga transportada no puede exceder la capacidad


mxima del carguero.

Al implementar computacionalmente el problema anterior haciendo uso de


OpenSolver se alcanzan los siguientes resultados:

La solucin ptima consiste en transportar los contenedores C1, C2, C3, C4, C8, C9 y
C10, con un valor ptimo de 700 (toneladas), es decir, se utiliza la capacidad completa
del carguero. Notar que otra solucin ptima consiste en transportar los contenedores
C1, C3, C4, C5, C6, C7, C8 y C9 lo que reporta un similar valor en la funcin objetivo.

Problema de la mochila simple


Observar que en un problema de la mochila 0-1, si para cada tipo de tem el beneficio y
los pesos son idnticos (vi=wi), entonces el problema quedara formulado de la
siguiente forma

Por tanto si existe un vector xi tal que


, entonces esa ser una
solucin al problema. Si existe una solucin xi de este tipo, resolver el problema de la
mochila realmente es resolver el problema de la suma de subconjuntos. Adems si el
conjunto de los pesos de los elementos es una secuencia sper-creciente, es decir, se
verifica que:

Entonces se dice que se trata de un problema de la mochila simple o tambin


problema de la mochila tramposa. Este tipo de problemas tiene importantes
aplicaciones en el mundo de la criptografa.
PROBLEMA DE LA MOCHILA DE MLTIPLE ELECCIN
Si en un problema de la mochila 0-1 los tems estn subdivididos en k clases,
denotadas por Ni, y exactamente un tem tienen que ser tomado de cada clase,
entonces hablamos del problema de la mochila de mltiple eleccin.

PROBLEMA DE LA MOCHILA MLTIPLE


Si en un problema de la mochila 0-1 tenemos "n" tems y m mochilas con capacidades
Wi entonces tenemos el problema de la mochila mltiple.
Un caso especial del problema de la mochila mltiple es cuando los beneficios son
iguales a los pesos y todas las mochilas tienen la misma capacidad. Entonces se le
llama problema de la mltiple suma de subconjuntos.

Cdigo de algoritmo de GREEDY


MONEDAS:

#include<iostream>
#define max 30
int C[max];
using namespace std;
//saca el tamao del vector-------------------------------int tama(int tabla[max])
{
int tam=0;
while (tabla[tam]!=' ')
tam++;
return tam;
}
//ordena vector -------------------------------void burbuja (int n )
{
int B;

for (int i=n-1;i>=1;i--)


for(int j=0;j<=i-1;j++)
if (C[j]>C[j+1])
{
B=C[j];
C[j]=C[j+1];
C[j+1]=B;
}
}
//principal
int main(){
int i=0,m,mon,t,n,cant[max],l,sol[max];
char continuar;
cout<<"ingrese sistema monetario"<<endl;
while(1){//almacena
cin>>C[i]; i++;
cout<<"desea continuar s/n";
cin>>continuar;
if(continuar=='n') break;}
//fin de almacena
burbuja(i);//llama ordenacin
//cantidades
cout<<"ingrese cantidad de monedas"<<endl;
for(t=0;t<i;t++)
{
cout<<"ingrese cantidad de la moneda "<<C[t]<< " : ";
cin>>cant[t];
}
//fin de cantidades
cout<<"ingrese cantidad a cambiar"<<endl;
cin>>mon;
int d;
m=i-1; n=0; l=t;
l--; t=0;
//cuerpo o desarrollo------------------------------------------------while(n!=mon&& m!=-1)
{
d=cant[l];

do{
n=n+C[m];
if(n>mon)//verifica
{ n=n-C[m];
if(m==-1) {cout<<"no es posible cambiar"; break;}
}
else {sol[t]=C[m];t++;}//fin de verifica
d--;
}while(d!=0);
m--;l--;
}
//fin del desarrollo---------------------------------------------------if(mon==n){//solucion
cout<<"El reparto de algoritmo greedy es: "<<endl;
for(i=0; i<t;i++)
cout<<sol[i]<<endl;}
else{cout<<"no es posible cambiar ";}//no solucion
return 0;}

ACTIVIDADES:

#include<iostream>
#define MAX 50
using namespace std;
int S[MAX] ; // solucion
int c[MAX] ; // comienzo de cada actividad
int f[MAX] ; // final de cada actividad
/* Ingreso de datos
------------------------------------------------------------------------*/
void ingresar_actividades(int n)
{
for(int i=0; i<n; i++)
{
do
{
cout << " Actividad " << i+1 << endl<< endl ;
cout << "\tinicio : " ; cin >> c[i] ;
cout << "\tfinal : " ; cin >> f[i] ;
cout << endl ;
}while( c[i] > f[i] ) ; // el inicio no puede ser mayor que el final

}
}
/* Mostrando solucion
------------------------------------------------------------------------*/
void mostrar_datos(int n)
{
cout<<" Actividades ingresadas. "<<endl<<endl ;
cout<<"\t\t Ai : " ;
for(int i=0; i<n; i++)
cout<< i+1 <<' ';
cout<<endl<<"\t\t-------------------------"<<endl ;
cout<<"\t inicio : " ;
for(int i=0; i<n; i++)
cout<< c[i] <<' ';
cout<<endl ;
cout<<"\t fin : " ;
for(int i=0; i<n; i++)
cout<< f[i] <<' ';
}
/* Ordenando actividades
------------------------------------------------------------------------*/
void Ordenar ( int n)
{
int aux1, aux2, aux3, band = 1 ;
for(int i=n-1; i>0 && band==1; i--)
{
band = 0;
for(int j=0; j<i; j++)
{
if( f[j] > f[j+1])
{
aux1 = f[j] ;
f[j] = f[j+1] ;
f[j+1] = aux1 ;
aux2 = c[j] ;
c[j] = c[j+1] ;
c[j+1] = aux2 ;
band = 1 ;
}
}
}
mostrar_datos(n) ;
}
/* Devolviendo solucion

------------------------------------------------------------------------*/
void devolver_solucion()
{
cout<<endl<<" Solucion voraz: \n\n\t" ;
int i = 0 ;
while( 1 )
{
cout<<"A" << S[i] + 1 << " " ;
i ++ ;
if(S[i]==0)
break ;
}
}
/* Algoritmo de solucion
------------------------------------------------------------------------*/
void algoritmo_seleccion( int n )
{
Ordenar ( n ) ;
int z , k = 1 ;
S[0] = 0 ;
z=0;
for( int i=1; i<n; i++ )
{
if( c[i] >= f[z] )
{
S[k] = i ; // actividad seleccionada
z=i;
k++ ;
}
}

devolver_solucion() ;
}
/* Funcion Principal
------------------------------------------------------------------------*/
int main()
{
int N ; // numero de actividades
cout<<" Ingrese numero de actividades: ";
cin>> N ;
cout<<endl ;

ingresar_actividades( N );
system("cls");
algoritmo_seleccion( N ) ;
cout<<endl<<endl ;
system("pause");
return 0 ;
}

Linkografa:

http://elvex.ugr.es/decsai/algorithms/slides/4%20Greedy.pdf
http://www.fceia.unr.edu.ar/lcc/t312/archivos/09.ED.Practica.Greedy.pdf
http://www.fceia.unr.edu.ar/lcc/t312/archivos/09.ED.Greedy.handout.pdf

You might also like