Вы находитесь на странице: 1из 42

Algoritmos voraces

(Greedy algorithms)

Algoritmos voraces
Tambin conocidos como algoritmos vidos o
miopes
Su caracterstica es que toman decisiones basndose
en la informacin que tienen en forma inmediata, sin
tener en cuenta los efectos que esto pueda tener en
el futuro, es decir, nunca reconsidera su decisin, sea
cual fuera la situacin que ocurrir ms adelante
Se confa que la decisin tomada sea la mejor para la
solucin general del problema...

Algoritmos voraces
Utilizados en aplicaciones de optimizacin...
Son algoritmos fciles de disear y de implementar
pero NO siempre llevan a una solucin correcta del
problema
Cuando si obtienen la solucin correcta, lo hacen de
una manera eficiente
Sin embargo, es difcil demostrar formalmente cuando
un algoritmo voraz es correcto o no...

Ejemplo: cambio
El cliente compra una
mercancia de 23 pesos y
paga con $100
Hay que dar 77 pesos
con monedas de $20,
$10, $5 y $1
Se considera ptima la
solucin que entregue
las menos monedas.

Algoritmo cambio
Repetir:
Elegir la moneda ms grande
que no supere el cambio a entregar
Pasarla al montn del cambio

Seleccin

Factibilidad

Hasta que se alcance el cambio exacto (o no se


pueda)
Verificacin de la solucin

Ejemplo cambio
Tomar moneda de:

20
20
20
10
5
1
1

Llevamos:

- 20
- 40
- 60
- 70
- 75
- 76
- 77

Estructura general de un
algoritmo voraz
Se apoya en un conjunto original de datos (C), y el
conjunto resultante que contendr la solucin (S)
S=
Mientras C <> y no se haya encontrado la solucin:
x = seleccin de mejor candidato de C
C = C - {x}
si es factible S {x} entonces S = S {x}
Si S tiene la solucin devolver S, sino, no hay solucin.

El problema del rbol de


extensin mnima
Dado un grafo no dirigido y ponderado
Cul es el costo MNIMO para tener a todos los
vrtices conectados?
La solucin del problema, implica que se obtenga un
subgrafo del grafo original, en el que NO se tengan
ciclos
por lo tanto, la solucin obtiene un RBOL que es
llamado de EXTENSIN MNIMA por la optimizacin
que se realiza.

Ejemplo
Cmo puedo tener conectadas a las siguientes
ciudades por un costo mnimo?
45
Monterrey

13

Reynosa
32

19

Cd. Victoria

Saltillo

21
Tampico
57

96
Mxico DF

Ejemplo
Cmo puedo tener conectadas a las siguientes
ciudades por un costo mnimo?
45
Monterrey

13

Reynosa
32

19

Cd. Victoria

Saltillo

21
Tampico
57

96
Mxico DF

Algoritmo general para


obtener el rbol de extensin
mnima
Sea el grafo G = (V, A) en donde V es el conjunto de
vrtices y A el conjunto de arcos de la forma (vi, vj).

La forma en que se
hace la seleccin
determina el algoritmo
especfico

S=
Mientras (no se haya resuelto el problema)
Seleccionar un arco de A de acuerdo a cierta poltica de
optimizacin --> SELECCION
Si al agregar ese arco a S no genera un ciclo en el subgrafo,
agregarlo a S --> FACTIBILIDAD
Si (V,S) cubre todos los vrtices, el problema se ha resuelto
> VERIFICACIN DE LA SOLUCIN

--

Algoritmo de Prim
S=
Y = {v1}
Mientras (no se haya resuelto el problema)
Seleccionar el vrtice de V-Y que sea el ms
cercano (menor peso) a alguno de los vrtices
en Y.
Agregar el vrtice a Y.
Agregar el arco correspondiente a S.
Si Y = V el problema se ha resuelto.

Ejemplo
2

A
12
10

6
D

S=
Y = {vA}

B
9

3
E

V-Y = {vB, vC, vD, vE}


Seleccionar el arco
de menor costo de
Y a V-Y

Ejemplo
2

A
12
10

6
D

S = {(vA, vB)}

B
9

Y = {vA, ,vB}
5

3
E

V-Y = {vC, vD, vE}


Seleccionar el arco
de menor costo de
Y a V-Y

Ejemplo
2

A
12
10

6
D

S = {(vA, vB),(vB, vE)}

B
9

Y = {vA, ,vB , vE}


5

3
E

V-Y = {vC, vD}


Seleccionar el arco de
menor costo de Y a
V-Y

Ejemplo
2

A
12
10

6
D

S = {(vA, vB),(vB, vE),


(vE, vC)}

B
9

3
E

Y = {vA, ,vB , vE , vC}


V-Y = {vD}
Seleccionar el arco de
menor costo de Y a
V-Y

Ejemplo
2

A
12
10

6
D

S = {(vA, vB),(vB, vE),


(vE, vC), (vC, vD) }

Y = {vA, ,vB , vC , vD , vE}

3
E

V-Y =
Puesto que Y es igual a
V, se ha encontrado
la solucin

Implementacin Prim
Estructuras de datos:
W: Matriz de adyacencias.
nearest[i]: Indice del vrtice de Y ms cercano a vi.
distance[i]: peso del arco entre vi y el vrtice de
nearest[i].

Ideas algoritmo
Se inicializa nearest[i] con 1 y
distance[i] con W[1][i].
Sigue el ciclo para n-1 vrtices que pasan a Y
Se encuentra el mnimo de distance[i], el ndice es
vnear.
Se aade a F el vrtice entre vnear y nearest[vnear]
Se hace distance[vnear] = -1 (pasa a Y)
Se actualizan distance y nearest

Complejidad
Dos ciclos, cada uno con n-1 iteraciones dentro
de un repeat
La complejidad no depende de los datos, y es
2(n-1)(n-1), o sea de orden O(n2)

Algoritmo de Kruskal
S=
Y = subconjuntos disjuntos de V, cada uno con cada uno de
los vrtices de V
Ordenar los arcos en A en forma ascendente de acuerdo a
su peso.
Mientras (no se haya resuelto el problema)
Seleccionar el siguiente arco de A.
Si el arco conecta 2 vrtices de Y, unir los subconjuntos y
aadir el arco a S.
Si todos los subconjuntos se han unido, el problema se ha
resuelto.

Ejemplo
2

A
12
10

6
D

S=
Y = {{vA} {vB} {vC} {vD} {vE}}

B
9

3
E

A = {(vA, vB), (vC, vE), (vB, vE),


(vC, vD), (vD, vE), (vB, vC), (vA,
vD), (vA, vC)}
Seleccionar el arco de menor
costo de A y si une a dos
subconjuntos de Y, unirlos y
agregar el arco a S

Ejemplo
2

A
12
10

6
D

S = {(vA, vB)}

B
9

Y = {{vA ,vB} {vC} {vD} {vE}}

3
E

A = {(vC, vE), (vB, vE), (vC, vD),


(vD, vE), (vB, vC), (vA, vD), (vA,
vC)}
Seleccionar el arco de menor
costo de A y si une a dos
subconjuntos de Y, unirlos y
agregar el arco a S

Ejemplo
2

A
12
10

6
D

S = {(vA, vB), (vC, vE)}

B
9

Y = {{vA ,vB } , {vC ,vE} {vD}}

A = {(vB, vE), (vC, vD), (vD, vE),


(vB, vC), (vA, vD), (vA, vC)}

3
E

Seleccionar el arco de menor


costo de A y si une a dos
subconjuntos de Y, unirlos y
agregar el arco a S

Ejemplo
2

A
12
10

6
D

S = {(vA, vB), (vC, vE), (vB, vE)}

B
9

Y = {{vA ,vB ,vC ,vE} {vD}}

A = {(vC, vD), (vD, vE), (vB, vC),


(vA, vD), (vA, vC)}

3
E

Seleccionar el arco de menor


costo de A y si une a dos
subconjuntos de Y, unirlos y
agregar el arco a S

Ejemplo
2

A
12
10

6
D

S = {(vA, vB), (vC, vE), (vB, vE) ,


(vC, vD)}

Y = {{vA ,vB ,vC , vD ,vE}}

3
E

A = {(vD, vE), (vB, vC), (vA, vD),


(vA, vC)}
Puesto que Y slo contiene un
subconjunto con todos los
vrtices, S contiene la
solucin.

Implementacin de los
algoritmos
Requieren de un tipo de dato conjunto, que permita
trabajar con las operaciones de conjuntos (unin,
diferencia, aadir).
Prim se apoya en la matriz de transiciones, y en
arreglos auxiliares (ver detalle en libro).
Kruskal requiere de la implementacin del tipo de dato
conjunto disjunto (ver detalle en libro).
Los HEAPS pueden ayudar a obtener otras versiones
eficientes de implementacin.

Cmo se comprueba que


los algoritmos son
correctos?
En el caso de la programacin dinmica, basta
comprobar que se cumple el principio de optimalidad
para saber que se tiene un algoritmo vlido
En el caso de divide y vencers, la recursividad est
fundamentada, y comprueba la validez del
algoritmo
En el caso de algoritmos voraces, se requiere una
demostracin matemtica especfica dependiendo del
problema, y normalmente es ms compleja (ver

Cmo es el
comportamiento de los
algoritmos?
Prim es un algoritmo con un comportamiento igual
para todos los casos, que tiene una complejidad de
tiempo de orden O(n2), siendo n la cantidad de
vrtices en el grafo (ver detalle en el libro).
Kruskal es un algoritmo en el que influye la cantidad
de arcos en su comportamiento. Su peor caso, tiene
una complejidad de tiempo de orden O(n2 log2n) o
O(m log2m), siendo n la cantidad de vrtices y m la
cantidad de arcos (ver detalle en el libro).

Cul de los dos


algoritmos es mejor
utilizar?

Cuntos arcos puede tener un grafo no dirigido


conectado de n vrtices?
MINIMO: n - 1 arcos
MAXIMO: n (n - 1) / 2 arcos

Prim O(n2) vs. Kruskal O(m log2m)


Por lo tanto, para un grafo con pocos arcos, Kruskal
resultar ms eficiente, y
para un grafo muy denso (altamente conectado), Prim
funcionar mejor...

EJEMPLO
1

32

17

18

45

10

59

28

25

PRIM

10

12

32

17

KRUSKAL

18

45

10

59

28

25

6
6

12

10

El problema del
camino ms corto
Qu pasara si en determinada aplicacin se requiere
conocer el camino ms corto de un vrtice a otro?
El Algoritmo de Floyd obtiene el camino ms corto de
TODOS los vertices hacia TODOS los vrtices y tiene
un comportamiento de O(n3)
Si slo se requiere el anlisis para un slo camino,
podra hacerse de una manera ms eficiente?
SI la propuesta del Algoritmo de Dijkstra resuelve el
problema en O(n2).

Algoritmo de Dijkstra
S=
Y = {v1}
Mientras (no se haya resuelto el problema)
Seleccionar el vrtice de V-Y que tenga el camino
ms corto desde v1 usando slo a los vrtices en Y
como intermediarios.
Agregar el vrtice a Y.
Agregar el arco que llega a al vrtice seleccionado
a S.
Si Y = V el problema se ha resuelto.

Ejemplo
2

A
12
10

6
D

S=
Y = {vA}

B
9

3
E

V-Y = {vB, vC, vD, vE}


Seleccionar el vrtice de
V-Y que tenga el
camino ms corto
desde vA, pasando por
los vrtices de Y

Ejemplo
2

A
12
10

6
D

S = {(vA, vB)}

B
9

Y = {vA, vB}
5

3
E

V-Y = {vC, vD, vE}


Seleccionar el vrtice de
V-Y que tenga el
camino ms corto
desde vA, pasando por
los vrtices de Y

Ejemplo
2

A
12
10

6
D

S = {(vA, vB),(vB, vE)}

B
9

Y = {vA, vB , vE}
5

3
E

V-Y = {vC, vD}


Seleccionar el vrtice de
V-Y que tenga el
camino ms corto
desde vA, pasando por
los vrtices de Y

Ejemplo
2

A
12
10

6
D

S = {(vA, vB) ,(vB, vE),


(vE, vC)}

B
9

3
E

Y = {vA, vB , vC, vE}


V-Y = {vD}
Seleccionar el vrtice de
V-Y que tenga el
camino ms corto
desde vA, pasando por
los vrtices de Y

Ejemplo
2

A
12
10

6
D

S = {(vA, vB) ,(vB, vE),


(vE, vC), (vA, vD) }

B
9

3
E

Y = {vA, vB , vC, vD, vE}


V-Y =
Puesto que Y es igual a
V, se ha encontrado
la solucin

Implementacin del
Algoritmo de Dijkstra
Utiliza a la matriz de adyacencias del grafo (W).
Se auxilia de un arreglo L, indexado de 2 a n, en donde
guardar la longitud de los caminos ms cortos del
vrtice v1 al vrtice vi, usando slamente a los vrtices
del conjunto Y como intermediarios.
Se auxilia de un arreglo T, indexado de 2 a n, en donde
guardar el ndice del vrtice v, cuyo arco (v,vi) es el
ltimo arco en el camino ms corto de v1 a vi usando
solamente a los vrtices del conjunto Y como

Algoritmo de Dijkstra
S = ;
Inicializa los
arreglos auxiliares:
for (i = 2; i <=n; i++)
L con los caminos directos
{ L[i] = W[1][i];
a partir de v
T con v pues no se ha
T[i] = 1; }
pasado por otro vrtice
Repetir n-1 veces: //para incluir los vrtices en Y
Busca el menor
{ min = ;
de los caminos
ms cortos a
for (i = 2; i<=n; i++)
partir de v ,
descartando a los
if ( 0 <= L[i] <= min)
ya alcanzados
{ min = L[i]; vmin = i; }
continua...
1

Algoritmo de Dijkstra
e = arco formado por T[vmin] y vmin;
Aadir e a S;
for (i=2; i<=n; i++)
if (L[vmin]+W[vmin][i] < L[i])
{
L[i] = L[vmin]+W[vmin][i];
T[i] = vmin; }
L[vmin] = -1; //control para que ya no se considere en la bsqueda del menor
}

Trabajo 1: Mximo 2
personas
Programar en Pyton, Java, C, C++, los
algoritmos de Prim, Kruskal y Dikstra. Luego
Compararlos terica como empricamente.
Fecha Entrega: 09 Mayo 2015 15:30 Hrs
Entregar Cdigo e Informe del trabajo.

Вам также может понравиться