Está en la página 1de 16

Análisis y Diseño de Algoritmos

Algoritmos Voráces
Cesar Liza Avila

website : www.cesarliza.com
e-mail : creadores@hotmail.com

César Liza Avila www.cesarliza.com


Algoritmos Voráces

También conocidos como algoritmos glotones, ávidos o Greedy.

Son aplicados a problemas de optimización.

Es de fácil implementación.

Suelen ser muy eficientes.

En cada paso toman la mejor decisión en base a la información que tienen en


ese momento sin tomar en cuenta si conviene al objetivo final.
“una política óptima necesita subpolíticas óptimas”

En cada paso un elemento se evalúa y se incluye o no en la solución, y nunca


mas se reconsidera la decisión.

Es obvio que esta estrategia no siempre conducirá a soluciones óptimas


globales.

César Liza Avila www.cesarliza.com


Algoritmos Greedy famosos
Disjktra, Prim, Kruskal (los veremos mas adelante).

Algoritmos Greedy usados como Heurística


Se puede abordar problemas donde es difícil o costoso encontrar la solución
óptima, puede ser adecuado encontrar una solución aproximada.

Problema del agente viajero


Un agente viajero debe recorrer una serie de ciudades y volver al punto de
partida recorriendo la menor distancia posible y sin pasar dos veces por la
misma ciudad.

César Liza Avila www.cesarliza.com


Problema del cambio de monedas
Un sistema monetario esta formado por monedas de valores Vi, se pide
descomponer un monto utilizando la menor cantidad posible de monedas.

El algoritmo ávido solo funciona si el


sistema monetario esta compuesto
por monedas de 1, p, p2, p3, … pn. y
se dispone de cantidad ilimitada de
monedas.

César Liza Avila www.cesarliza.com


# include <iostream.h>
#include <iostream.h> Código void main(void)
{
void main(void) int moneda[]= {100, 25, 10, 5, 1};
{ int moneda[ ] = {100, 25, 10, 5, 1}; int veces [] = { 0, 0, 0, 0, 0};
int veces [ ] = { 0, 0, 0, 0, 0}; int n=5;
int n=5; int monto, i;
cout<<"Monto:"; cin>>monto;
int monto, i;
for(i=0; i<n; i++)
cout<<"Monto:"; {
cin>>monto; veces[i] = monto/moneda[i];
monto = monto%moneda[i];
for(i=0; i<n; i++) }
{
while( monto>= moneda[i] ) for(i=0; i<n; i++)
cout<<"monedas " << moneda[i]
{
<< " cantidad "<< veces[i]<<endl;
veces[i]++; }
monto-= moneda[i];
}
}
for(i=0; i<n; i++)
cout<<"monedas " << moneda[i]
<< " cantidad "<< veces[i]<<endl;
}
César Liza Avila www.cesarliza.com
Problema de programación de tareas

Una contratista desea atender a sus clientes, de tal


manera que el tiempo medio de atención para cada
cliente sea el mínimo.

Se conoce de antemano un estimado de lo que tomará


atender a cada cliente.

Implemente un programa que muestre el orden en que


serán atendidos los clientes.

César Liza Avila www.cesarliza.com


Programación de tareas
Consideremos 3 clientes, C1, C2 y C3 con tiempos de atención, 8, 4 y 6
respectivamente.

Es obvio que el tiempo total de trabajo del contratista será 8+4+6=18, pero el
tiempo medio de espera del cliente varia según el orden en que los atienda.

Orden Tiempo de Tiempo de Tiempo de Tiempo medio


atención C1 atención C2 atención C3 de Atención
C1 C2 C3 8 8+4 8+4+6 12.7
C1 C3 C2 8 8+6 8+6+4 13.3
C2 C1 C3 4+8 4 4+8+6 11.3
C2 C3 C1 4+6+8 4 4+6 10.7
C3 C1 C2 6+8 6+8+4 6 12.7
C3 C2 C1 6+4+8 6+4 6 11.3

Para minimizar el tiempo medio de atención debemos atenderlos en el


orden C2 C3 y C1.

César Liza Avila www.cesarliza.com


void leerArray(int n, struct cliente cte[ ])
Código fuente { for (int i=0; i<n; i++)
{ cout << "Codigo cliente: "<<i << ": ";
#include <iostream.h> cin >> cte[i].codigo;
#define MAX 50 cout << "Tiempo estimado: "<<i << ": ";
cin >> cte[i].tiempo;
struct cliente { int codigo;
cout<<endl;
int tiempo; }
}; }
void leerArray(int, struct cliente[]); void quickSort(int primero, int ultimo, struct cliente cte[ ])
void quickSort(int, int, struct cliente[]); { int i=primero;
void main(void) int j=ultimo;
{ struct cliente cte[MAX]; struct cliente central= cte[(primero+ultimo)/2];
struct cliente temp;
int n, tiempoAtencion=0, tiempoTotal=0;
do
cout<<"Nro de Clientes:"; cin>>n; {
leerArray(n, cte); while(central.tiempo > cte[i].tiempo) i++;
quickSort(0, n-1, cte); while(central.tiempo < cte[j].tiempo) j--;
if (i<=j)
for(int i=0; i<n; i++) {
{ tiempoAtencion += cte[i].tiempo; temp = cte[i];
cte[i] = cte[j];
tiempoTotal += tiempoAtencion;
cte[j] = temp;
cout<<"Cliente "<< cte[i].codigo i++;
<< " atendido en: " j--;
<< tiempoAtencion }
<<" unidades de tiempo"<<endl; } while(i<=j);
}
cout<<"Tiempo medio de atención:“ if (primero<j) quickSort(primero, j, cte);
if (ultimo >i) quickSort( i, ultimo, cte);
<<(float)tiempoTotal/n<<endl;
}
} César Liza Avila www.cesarliza.com
El Problema de
la Mochila

Supóngase que se tiene n objetos distintos y una mochila.

Cada objeto tiene asociado un peso wi y un valor vi

La mochila puede llevar un peso que no sobrepase su


capacidad de carga W.

César Liza Avila www.cesarliza.com


Objetivo
• Llenar la mochila de tal forma que se maximice el
valor de los objetos transportados en ella.

• Hay que tener en cuenta que la suma de los pesos de


los objetos seleccionados no debe superar la
capacidad máxima W de la mochila.

Matemáticamente:
Maximizar: Sujeto a la restricción:
n
n
∑xv
i =1
i i ∑x w ≤ M
i =1
i i

César Liza Avila www.cesarliza.com


Tipos de Mochila
• La mochila fraccionaria (siempre funciona
la estrategia voraz)

• La mochila entera ( 0/1) (no siempre


funciona la estrategia voraz)

César Liza Avila www.cesarliza.com


La Mochila Fraccionaria

• Es aquella en la cual
se pueden utilizar
cantidades no enteras
de los objetos.

• Se supone que no hay


mas de una unidad de
cada objeto

• Mejor Método un
“Algoritmo Voraz”

En el diagrama vemos la mochila entera con


estrategia voraz. Se sabe que no siempre funciona
César Liza Avila www.cesarliza.com
La Mochila Fraccionaria
# include <iostream.h> cout<<"Capacidad de la mochila: ";
# include <iomanip.h> cin>>w;
#define MAX 100 cout<<"No. de objetos: ";
void mochilaAvida(int, int, struct objetos[ ], float[ ]); cin>>n;
void ingresoObjetos(int, struct objetos[ ]); ingresoObjetos(n, m);
void impSolucion(int, float[ ], struct objetos[ ]); Burbuja(n, m) ;
void Burbuja(int, struct objetos[ ]); cout<<endl<<"Ordenados segun contribucion“
struct objetos <<endl;
{ float peso; for(int i=0; i<n; i++)
float valor; {
float ratio; cout<<"Peso :"<<setw(4)<< m[i].peso
}; <<" Valor:"<<setw(4)<< m[i].valor
void main(void) <<" Ratio:"<<setw(4)<< m[i].ratio<<endl;
{ struct objetos m[MAX]; }
float sol[MAX]; mochilaAvida(n, w, m, sol);
int n, w; impSolucion(n, sol, m) ;
cout<<"PROBLEMA DE LA MOCHILA }
Fraccionaria“ <<endl;
cout<<"Usando Algoritmo Avido"<<endl<<endl;

César Liza Avila www.cesarliza.com


La Mochila Fraccionaria
void ingresoObjetos(int n, struct objetos m[ ])
{ for(int i=0; i<n; i++)
{ cout<<endl;
cout<<"Peso :"; cin>> m[i].peso;
cout<<"Valor:"; cin>> m[i].valor;
m[i].ratio = m[i].valor/m[i].peso;
}
}
// ordena de mayor a menor segun el ratio
void Burbuja(int n, struct objetos x[])
{ int i,j;
struct objetos temp;
for (i=1; i<n; i++)
for ( j=n-1; j>=i; j--)
if ( x[j-1].ratio < x[j].ratio )
{ temp = x[j-1];
x[j-1] = x[j];
x[j] = temp;
}
}
César Liza Avila www.cesarliza.com
La Mochila Fraccionaria
void mochilaAvida(int n, int w, void impSolucion( int n, float sol[ ],
struct objetos m[], float sol[ ]) struct objetos m[ ] )
{ {
int i; float valor=0;
for(i=0; i<n; i++) cout<<endl<<"Se necesitan:" <<endl;
sol[i]=0; for(int i=0; i<n; i++)
{
float pesoActual=0; int xx=0; cout<<setw(6)<<sol[i]
<<" objetos de peso “
for(i=0; pesoActual<w && i<n; i++ ) << setw(6)<< m[i].peso
{ <<" y valor"<<setw(6)
if( (pesoActual+m[i].peso) <=w ) <<m[i].valor<<endl;
sol[i]=1;
else valor+= sol[i]*m[i].valor;
sol[i]+= (w-pesoActual)/m[i].peso; }
pesoActual += sol[i]*m[i].peso; cout<<endl
} <<"Valor optimo de la carga:"
} <<valor<<endl;
}

César Liza Avila www.cesarliza.com


La Mochila Fraccionaria

César Liza Avila www.cesarliza.com

También podría gustarte