Está en la página 1de 53

Estructuras de Datos y Algoritmos

Facultad de Informtica a Universidad Politcnica de Valencia e

Curso 2009/2010 Tema 6: Algoritmos de grafos

FI UPV: Curso 2009/2010

EDA-6

TEMA 6. Algoritmos de grafos


Conceptos previos Representacin de grafos: matriz de adyacencia y listas de adyacencia (tema 4). o Recorridos de grafos en amplitud y en profundidad (tema 4). Algoritmos voraces (tema 5). Objetivos Algoritmos para la construccin del rbol de expansin de coste m o a o nimo. Algoritmos para la bsqueda del camino m u nimo en un grafo. Algoritmos para calcular el ujo mximo en un grafo. a Contenidos Arbol de expansin de coste m o nimo: Algoritmos de Kruskal y Prim. Caminos ms cortos: Algoritmo de Dijkstra. a Flujo mximo: Algoritmo de Ford-Fulkerson/Edmonds-Karp. a

Bibliograf a Introduction to Algorithms, de Cormen, Leiserson y Rivest (cap tulos 24, 25 y 26)
FI UPV: Curso 2009/2010 Pgina 6.1 a

EDA-6

1. ARBOL DE RECUBRIMIENTO DE COSTE M INIMO


Arbol de recubrimiento de un grafo no dirigido G = (V, A): es un rbol libre T = (V , A ) tal que V = V y A A. a Problema: Dado un grafo conexo ponderado no dirigido G = (V, A, p), encontrar un rbol de recubrimiento de G, T = (V, A ), tal que la suma a de los pesos de las |V | 1 aristas de T sea m nimo.

a
8

a
2 9 8

b
6 6

4 5

e
1 3

b
6 6

4 5

e
1 3

FI UPV: Curso 2009/2010

Pgina 6.2 a

EDA-6

1. ALGORITMO DE KRUSKAL
Idea voraz: construir incrementalmente un bosque (de recubrimiento), seleccionando en cada paso una arista (u, v) A tal que: No se cree ningn ciclo. u Produzca el menor incremento de peso posible. El resultado del algoritmo es un rbol libre (no enraizado) formado por los mismos a vrtices del grafo y un subconjunto de |V | 1 aristas. e
1 2 3 4 5 6 7 8 9 10 11 12 13

GrafoPonderado* Kruskal (GrafoPonderado *G) { // Pseudo-cdigo o // El arbol de recubrimiento tiene los mismos vrtices que G: e GrafoPonderado *MST = new GrafoPonderado(G->vertices); // Cola de prioridad, las aristas se extraen por menor peso: ColaPrioridad Q(G->aristas); arista a; while (MST->NumAristas() < MST->NumVertices()-1 && Q.extraer(a)) { if (a no crea un ciclo en MST) MST->insertarArista(a); } return MST; }
Pgina 6.3 a

FI UPV: Curso 2009/2010

EDA-6

1. ALGORITMO DE KRUSKAL
Problema: Cmo vericar ecientemente la condicin de no crear ciclo? o o Solucin: Mantener una coleccin de subconjuntos (disjuntos) con los vrtices o o e de cada rbol del bosque: Una arista (u, v) no crear ciclo si u y v estn en a a a distintos subconjuntos componentes conexas estructurar el conjunto de aristas seleccionadas como un MFset de vrtices. e

Problema: Cmo seleccionar ecientemente la arista de menor peso en cada o iteracin? o Solucin: Manteniendo las aristas en una cola de prioridad (por ejemplo, un o MinHeap) organizadas segn su peso. u

FI UPV: Curso 2009/2010

Pgina 6.4 a

EDA-6

1. ALGORITMO DE KRUSKAL
1 2 3 4 5 6 7 8 9 10 11 12 13

GrafoPonderado* Kruskal (GrafoPonderado *G) { // Pseudo-cdigo o GrafoPonderado *MST = new GrafoPonderado(G->vertices); ColaPrioridad Q(G->aristas); mfset m(G->NumVertices()); while (MST->NumAristas() < MST->NumVertices()-1 && Q.extraer((u,v))) { if (m.find(u) != m.find(v)) { m.merge(u,v); MST->insertarArista((u,v)); } } return MST; }

FI UPV: Curso 2009/2010

Pgina 6.5 a

EDA-6

1. ALGORITMO DE KRUSKAL
El coste es O(|A| log |A|) construir MFsets de talla |V | O(|V |) construir MinHeap +O(|A|)

O(|A|) borrados en MinHeap+O(|A| log |A|) O(|A|) operaciones MFset +O(|A|)

En general, el coste es bastante inferior a la cota O(|A| log |A|): Si m es el nmero de iteraciones del bucle while, t u picamente m |V | y si |V | |A| |V |2, en la prctica, el coste est ms cercano a a a a |A| + |V | log |V |

FI UPV: Curso 2009/2010

Pgina 6.6 a

EDA-6

1. ALGORITMO DE KRUSKAL: UN EJEMPLO


Inicializacin o

a
8 9 4 6 5 2 1 (a,d) 2

(c,e) 1 (c,d) 4

b
6

e
3 (e,d) 3 (c,a) 4 (b,d) 6 (b,e) 5

d
(a,e) 9 (b,c) 6 (b,a) 8

FI UPV: Curso 2009/2010

Pgina 6.7 a

EDA-6

1. ALGORITMO DE KRUSKAL: UN EJEMPLO


NumAristas = 1

a
8 9 4 6 5 2 1

(a,d) 2 (e,d) 3 (c,d) 4

b
6

e
3 (b,c) 6

(c,a) 4

(b,d) 6

(b,e) 5

d
(a,e) 9 (b,a) 8

a
(c,e) 1

c e

FI UPV: Curso 2009/2010

Pgina 6.8 a

EDA-6

1. ALGORITMO DE KRUSKAL: UN EJEMPLO


NumAristas = 2

a
8 9 4 6 5 2 1

(e,d) 3 (c,a) 4 (c,d) 4

b
6

e
3 (b,c) 6

(b,a) 8

(b,d) 6

(b,e) 5

d
(a,e) 9

a
2 1

(a,d) 2

a d

c e

FI UPV: Curso 2009/2010

Pgina 6.9 a

EDA-6

1. ALGORITMO DE KRUSKAL: UN EJEMPLO


NumAristas = 3

a
8 9 4 6 5 2 1

(c,a) 4 (b,c) 6 (c,d) 4

b
6

e
3 (a,e) 9

(b,a) 8

(b,d) 6

(b,e) 5

a
2 1

e
3

(e,d) 3

a d c e

FI UPV: Curso 2009/2010

Pgina 6.10 a

EDA-6

1. ALGORITMO DE KRUSKAL: UN EJEMPLO


NumAristas = 3

a
8 9 4 6 5 2 1

(c,d) 4 (b,c) 6 (b,e) 5

b
6

e
3 (a,e) 9

(b,a) 8

(b,d) 6

a
2 1

e
3

(c,a) 4

a d c e

c
FI UPV: Curso 2009/2010

Pgina 6.11 a

EDA-6

1. ALGORITMO DE KRUSKAL: UN EJEMPLO


NumAristas = 3

a
8 9 4 6 5 2 1

(b,e) 5 (b,c) 6 (b,d) 6

b
6

e
3 (a,e) 9

(b,a) 8

a
2 1 (c,d) 4

e
3

a d c e

c
FI UPV: Curso 2009/2010

Pgina 6.12 a

EDA-6

1. ALGORITMO DE KRUSKAL: UN EJEMPLO


NumAristas = 4

a
8 9 4 6 5 2 1

(b,c) 6 (b,a) 8 (b,d) 6

b
6

e
3 (a,e) 9

a b c
FI UPV: Curso 2009/2010

2 1

e
3

(b,e) 5

a d c e b

d
Pgina 6.13 a

EDA-6

2. ALGORITMO DE PRIM
Idea voraz: Empezando por cualquier vrtice, construir incrementalmente un rbol de e a recubrimiento, seleccionando en cada paso una arista (u, v) del grafo tal que: Si se aade (u, v) al conjunto de aristas del rbol de recubrimiento obtenido hasta el n a momento no se cree ningn ciclo. u Produzca el menor incremento de peso posible.
1 2 3 4 5 6 7 8 9 10 11 12

GrafoPonderado* Prim (GrafoPonderado *G) { GrafoPonderado *MST = new Arbol(G->vertices); ConjuntoVertices S; S.insertar(vertice arbitrario de G); int NumVertices = 1; while ( NumVertices != G->vertices ) { arista a= argmin { peso(u,v) | u en S, v en V-S }; S.insertar(v); NumVertices++; MST->insertarArista(a); } return MST; }

FI UPV: Curso 2009/2010

Pgina 6.14 a

EDA-6

2. ALGORITMO DE PRIM
Problema: El coste cbico del algoritmo bsico de Prim est dominado por el coste u a a cuadrtico de la operacin de seleccin (argmin), que debe considerar todos los pares de a o o vrtices de S (ya seleccionados) y vrtices del grafo no incluidos en S. e e Solucin: Esta operacin puede implementarse con un coste lineal mediante la idea de o o Prim: Mantener para cada vrtice no seleccionado v V S el identicador e de un vrtice ya seleccionado u S ms prximo a l; es decir, e a o e v V S, P [v] = u = argmin p(x, v)
xS

Estos identicadores se pueden mantener en un vector P . Como en cada iteracin slo se o o aade un nuevo vrtice a S, P puede actualizarse en |V S| = O(|V |) pasos. n e

FI UPV: Curso 2009/2010

Pgina 6.15 a

EDA-6

2. ALGORITMO DE PRIM
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21

GrafoPonderado* Prim (GrafoPonderado *G) { GrafoPonderado *MST = new Arbol(G->vertices); VectVertBool S; VectVertVert P; VectVertFloat D; u = vertice arbitrario de G; for (k = 0; k < G->vertices; k++) { S[k] = false; P[k] = u; D[k] = peso(k,u); } S[u] = true; int NumVertices = 1; while ( NumVertices != G->vertices ) { for (k=0, minp = infinito; k < G->vertices; k++) if (!S[k] && minp > D[k]) { minp=D[k]; v=k; } S[v] = true; NumVertices++; MST->insertarArista((v,P[v])); for (k=0; k < G->vertices; k++) if (!S[k] && D[k] > peso(k,v)) { P[k]=v; D[k]=peso(k,v); } } return MST; }
Pgina 6.16 a

FI UPV: Curso 2009/2010

EDA-6

2. ALGORITMO DE PRIM: UN EJEMPLO

a
8 9 4 6 5 2 1

a
9

b
6

e
3

b c

4 1

e
3

d
P a e b e c e d e e 0

FI UPV: Curso 2009/2010

Pgina 6.17 a

EDA-6

2. ALGORITMO DE PRIM: UN EJEMPLO

a
8 9 4 6 5 2 1

a e
3

b
6

b c

4 5 1

e
3

d
P a c b e c 0 d e e 0

FI UPV: Curso 2009/2010

Pgina 6.18 a

EDA-6

2. ALGORITMO DE PRIM: UN EJEMPLO

a
8 9 4 6 5 2 1

a e
3

b
6

b c

2 5 1

e
3

d
P a d b e c 0 d 0 e 0

FI UPV: Curso 2009/2010

Pgina 6.19 a

EDA-6

2. ALGORITMO DE PRIM: UN EJEMPLO

a
8 9 4 6 5 2 1

a e
3

b
6

b c

2 5 1

e
3

d
P a 0 b e c 0 d 0 e 0

FI UPV: Curso 2009/2010

Pgina 6.20 a

EDA-6

2. ALGORITMO DE PRIM: UN EJEMPLO

a
8 9 4 6 5 2 1

a e
3

b
6

b c

2 5 1

e
3

d
P a 0 b 0 c 0 d 0 e 0

FI UPV: Curso 2009/2010

Pgina 6.21 a

EDA-6

2. ALGORITMO DE PRIM
Coste O(|V |2). Si se utiliza un MinHeap para guardar la informacin de los vectores P y D, podemos o obtener el m nimo de D y eliminarlo del conjunto en O(log |V |) Es necesario utilizar un MinHeap doblemente indexado para poder modicar los valores asociados a determinados vrtices. e El nmero de modicaciones en cada paso ser el grado del vrtice que aadimos u a e n al rbol. El coste de cada modicacin es O(log |V |) y el nmero total de a o u modicaciones a lo largo del algoritmo es O(|A|). Esta versin tiene, pues, un coste O(|A| log |V |), que es ventajoso para grafos o dispersos pero no para grafos densos.

FI UPV: Curso 2009/2010

Pgina 6.22 a

EDA-6

2. COMPARACION ENTRE PRIM Y KRUSKAL


Algoritmo de Prim: Versin sencilla de coste O(|V |2): Grafos densos o Listas de adyacencias y Heap O(|A| log |V |) Algoritmo de Kruskal: Con MFset: O(|A| log |A|) = O(|A| log |V |)

PRIM O(|V |2) Grafo Denso (|A| |V |2) Grafo Disperso (|A| |V |)
FI UPV: Curso 2009/2010

PRIM+Heap O(|A| log |V |) O(|V |2 log |V |) O(|V | log |V |)

KRUSKAL O(|A| log |A|) O(|V |2 log |V |) O(|V | log |V |)


Pgina 6.23 a

O(|V |2) O(|V |2)

EDA-6

3. CAMINOS DE M INIMO PESO EN GRAFOS DIRIGIDOS

Dado un grafo G = (V, A) dirigido y ponderado por una funcin o p : A R0, se dene el peso de un camino v0, v1, . . . , vk como la suma de los pesos de sus aristas:
k

u 10 s 5 x 2 3

9 7 2

p(v0, v1, . . . , vk ) =
i=1

p(vi1, vi)

Problema: Se quiere calcular el camino de m nimo peso (camino ms corto) y a su peso asociado desde un vrtice origen s a un vrtice destino t. e e

FI UPV: Curso 2009/2010

Pgina 6.24 a

EDA-6

3. CAMINOS DE M INIMO PESO Consideraciones

Si el grafo es no dirigido, podemos obtener un grafo dirigido sin ms que a duplicar cada arista {u, v} en cada direccin: (u, v) y (v, u) ambas con el o mismo peso. Por tanto, reducimos el problema al caso de grafos dirigidos. Si no hay una arista entre dos vrtices, podemos asumir que es equivalente e a que exista una arista con peso innito. Es posible que no exista el camino de menor coste entre dos vrtices s y t si e podemos llegar de s a t por un camino que incluya un ciclo de peso negativo. En tal caso, dando sucientes vueltas al ciclo podemos obtener caminos de peso arbitrariamente bajo.

FI UPV: Curso 2009/2010

Pgina 6.25 a

EDA-6

3. CAMINOS DE M INIMO PESO Algoritmos

Si todos los arcos tienen el mismo peso y ste es positivo, el algoritmo de e bsqueda primero en anchura (BFS, visto en tema 4) desde s nos proporciona u los costes de s a todos los dems vrtices. a e En el caso de grafos ac clicos, podemos utilizar tcnicas de programacin e o dinmica (se ver en la asignatura Algor a a tmica). En el caso de grafos con ciclos y pesos positivos, podemos utilizar el algoritmo de Dijkstra, que veremos a continuacin. o

FI UPV: Curso 2009/2010

Pgina 6.26 a

EDA-6

3. CAMINOS DE M INIMO PESO Algoritmos

Para grafos con ciclos y pesos negativos, es posible utilizar el algoritmo de Bellman-Ford, que adems puede detectar la presencia de ciclos de peso a negativo en el camino de s a t. Para calcular el coste de todos los caminos entre todos los pares de vrtices e del grafo, podemos iterar con uno de los algoritmos previos o bien utilizar el algoritmo de Floyd-Warshall. Existen otros algoritmos. Por ejemplo, cuando es fcil obtener una cota a optimista ajustada de la distancia (como la distancia eucl dea entre ciudades, etc.) es posible utilizar tcnicas de ramicacin y poda. e o

FI UPV: Curso 2009/2010

Pgina 6.27 a

EDA-6

3. ALGORITMO DE BELLMAN-FORD
Queremos calcular la distancia desde s. Mantenemos en un vector D una cota superior D[u] de la distancia de s a u. Utilizamos las aristas para mejorar la cota:
1

if (D[v] > D[u]+coste(u,v)) D[v] = D[u]+coste(u,v);

El algoritmo de Bellman-Ford es como sigue:


1 2 3 4 5 6 7 8 9 10 11

Inicializar vector D con D[v]=infinito excepto D[s]=0; Iterar |V|-1 veces: Para cada arista (u,v) del grafo: Si (D[v] > D[u]+coste(u,v)) D[v] = D[u]+coste(u,v); FinPara FinIterar Para cada arista (u,v) del grafo: Si (D[v] > D[u]+coste(u,v)) BUCLE NEGATIVO, PARAR FinPara Devolver D[t]

En el caso general (pesos negativos) es necesario procesar las aristas ms de a una vez.
FI UPV: Curso 2009/2010 Pgina 6.28 a

EDA-6

3. ALGORITMO DE DIJKSTRA
Requiere pesos positivos. Consigue procesar los vrtices y aristas una sola vez. e Utiliza el mismo vector de cotas superiores de la distancia desde s que BellmanFord. La diferencia estriba en que se puede garantizar un orden de seleccin o de vrtices de modo que cada vrtice seleccionado tiene en D la verdadera e e distancia, no slo una cota. o Es decir, este algoritmo mantiene un conjunto de vrtices S cuyo peso del camino e ms corto desde el origen s ya es conocido. El algoritmo va seleccionando el a vrtice u V S con la mejor estimacin del camino m e o nimo, lo inserta en S y utiliza las aristas que salen de u para actualizar la cota de los vrtices de e V S. Idea voraz: empezando en el vrtice origen s, construir incrementalmente e caminos a los dems vrtices seleccionando en cada paso un vrtice v no a e e seleccionado anteriormente tal que: Exista algn vrtice u V ya seleccionado previamente tal que (u, v) A. u e Al aadir (u, v) al camino que terminaba en u se produzca el menor n incremento de peso posible.

FI UPV: Curso 2009/2010

Pgina 6.29 a

EDA-6

3. ALGORITMO DE DIJKSTRA
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

int Dijkstra(GrafoDirigidoPonderado *G, int s, int t) { vectorVerticeFloat Distancia; vectorVerticeBoolean Fijados; for (int u = 0; u < G->vertices; u++) { Distancia[u] = infinito; Fijados[u] = false; } Distancia[s] = 0; while (not Fijados[t]) { min = infinito; for (int u=0; u < G->vertices; u++) if (!Fijados[u] && Distancia[u] < min) { min=Distancia[u]; v=u; } Fijados[v] = true; for ((v,w) arista de G) if (!Fijados[w] && Distancia[w] > Distancia[v] + peso(v,w)) Distancia[w] = Distancia[v] + peso(v,w); } return Distancia[t]; }
Pgina 6.30 a

FI UPV: Curso 2009/2010

EDA-6

3. ALGORITMO DE DIJKSTRA: UN EJEMPLO


u 10 s 5 x
Iteracin o 0 u Fijados

9 7 2

y
D[s] 0 D[u] D[v] D[x] D[y]

Por jar {s, u, v, x, y}

FI UPV: Curso 2009/2010

Pgina 6.31 a

EDA-6

3. ALGORITMO DE DIJKSTRA: UN EJEMPLO


u 10 s 5 x
Iteracin o 0 1 u s Fijados {s}

9 7 2

y
D[s] 0 0 D[u] 10 D[v] D[x] 5 D[y]

Por jar {s, u, v, x, y} {u, v, x, y}

FI UPV: Curso 2009/2010

Pgina 6.32 a

EDA-6

3. ALGORITMO DE DIJKSTRA: UN EJEMPLO


u 10 s 5 x
Iteracin o 0 1 2 u s x Fijados {s} {s, x}

9 7 2a

y
D[s] 0 0 0 D[u] 10 8 D[v] 14 D[x] 5 5 D[y] 7

Por jar {s, u, v, x, y} {u, v, x, y} {u, v, y}

FI UPV: Curso 2009/2010

Pgina 6.33 a

EDA-6

3. ALGORITMO DE DIJKSTRA: UN EJEMPLO


u 10 s 5 x
Iteracin o 0 1 2 3 u s x y Fijados {s} {s, x} {s, x, y}

9 7 2a

y
D[s] 0 0 0 0 D[u] 10 8 8 D[v] 14 13 D[x] 5 5 5 D[y] 7 7

Por jar {s, u, v, x, y} {u, v, x, y} {u, v, y} {u, v}

FI UPV: Curso 2009/2010

Pgina 6.34 a

EDA-6

3. ALGORITMO DE DIJKSTRA: UN EJEMPLO


u 10 s 5 x
Iteracin o 0 1 2 3 4 u s x y u Fijados {s} {s, x} {s, x, y} {s, x, y, u}

9 7 2a

y
D[s] 0 0 0 0 0 D[u] 10 8 8 8 D[v] 14 13 9 D[x] 5 5 5 5 D[y] 7 7 7

Por jar {s, u, v, x, y} {u, v, x, y} {u, v, y} {u, v} {v}

FI UPV: Curso 2009/2010

Pgina 6.35 a

EDA-6

3. ALGORITMO DE DIJKSTRA: UN EJEMPLO


u 10 s 5 x
Iteracin o 0 1 2 3 4 5
FI UPV: Curso 2009/2010

9 7 2a

y
D[s] 0 0 0 0 0 0 D[u] 10 8 8 8 8 D[v] 14 13 9 9 D[x] 5 5 5 5 5 D[y] 7 7 7 7
Pgina 6.36 a

u s x y u v

Fijados {s} {s, x} {s, x, y} {s, x, y, u} {s, x, y, u, v}

Por jar {s, u, v, x, y} {u, v, x, y} {u, v, y} {u, v} {v}

EDA-6

3. ALGORITMO DE DIJKSTRA: UN EJEMPLO


u 10 s 5 x
Iteracin o 0 1 2 3 4 5
FI UPV: Curso 2009/2010

9 7 2

y
D[s] 0 0 0 0 0 0 D[u] 10 8 8 8 8 D[v] 14 13 9 9 D[x] 5 5 5 5 5 D[y] 7 7 7 7
Pgina 6.37 a

u s x y u v

Fijados {s} {s, x} {s, x, y} {s, x, y, u} {s, x, y, u, v}

Por jar {s, u, v, x, y} {u, v, x, y} {u, v, y} {u, v} {v}

EDA-6

3. ALGORITMO DE DIJKSTRA Correccin del algoritmo de Dijkstra o


Es inmediato ver que D[v] d(s, v) en todo momento. Basta con ver que se alcanza la igualdad en cada vrtice que es jado. El caso inicial s es sencillo. e Para el resto de casos, sea u el vrtice a jar. Por reduccin al absurdo sobre e o el criterio de eleccin del vrtice, se demuestra que el camino de s a u utiliza o e unicamente vrtices jados. Es decir, no puede haber ningn camino ms corto e u a hasta u que pase por vrtices (ejemplo y) que no estn jados, pues en tal caso se e a eligir y antes que u: a

S
p2 s x p1 s y p1 x y

p2

Esta demostracin requiere que todos los pesos de las aristas sean positivos. Por o tanto, D[u] es la distancia del camino ms corto desde el origen s al vrtice u. a e
FI UPV: Curso 2009/2010 Pgina 6.38 a

EDA-6

3. ALGORITMO DE DIJKSTRA: COSTE

G implementado como una lista de adyacencia Existen |V | operaciones de extraccin del m o nimo en el vector, con un coste O(|V |). Cada vrtice v V se ja exactamente una vez, de forma que cada arista en la lista de e adyacencia se examina una unica vez. Debido a que el nmero total de aristas en G es u |A|, existen |A| iteraciones de este bucle, y cada iteracin tiene un coste O(1). o Por tanto, el coste total del algoritmo es O(|V |2 + |A|) = O(|V |2).

FI UPV: Curso 2009/2010

Pgina 6.39 a

EDA-6

3. ALGORITMO DE DIJKSTRA CON UN HEAP: COSTE


G implementado como una lista de adyacencia... ...y utilizando un MinHeap doblemente indexado H ordenado segn D u e indexado por los vrtices e (algoritmo de Dijkstra modicado): Existen |V | operaciones de extraccin del m o nimo en un Heap, con un coste O(log |V |). Hay que aadir el tiempo de construir el Heap, O(|V |). n En cada iteracin del bucle que recorre las aristas, si D[v] > D[u] + peso(u, v), se o deber modicar D[v] y, por tanto, modicar el Heap, con un coste O(log |V |). El nmero a u de veces que se ejecuta el bucle es O(|A|). Por tanto, el tiempo total del algoritmo ser O((|V | + |A|) log |V |) = O(|A| log |V |). a

FI UPV: Curso 2009/2010

Pgina 6.40 a

EDA-6

3. OBTENCION DEL VALOR Y DEL CAMINO MAS CORTO


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21

void Dijkstra(GrafoDirigidoPonderado *G, int s, int t, float *Distancia, int *Predecesor) { vectorBoolean Fijados; for (int u = 0; u < G->vertices; u++) { Distancia[u]=infinito; Fijados[u]=false; Predecesor[u]=s; } Distancia[s] = 0; while (not Fijados[t]) { // para calcular dist. Ao nicamente a t min = infinito; for (int u=0; u < G->vertices; u++) if (!Fijados[u] && Distancia[u] < min) { min=Distancia[u]; v=u; } Fijados[v] = true; for ((v,w) arista de G) if (!Fijados[w] && Distancia[w] > Distancia[v] + peso(v,w)) { Distancia[w]=Distancia[v]+peso(v,w); Predecesor[w]=v; } } // devolvemos por ref. Distancia y Predecesor (para recuperar camino) }
Pgina 6.41 a

FI UPV: Curso 2009/2010

EDA-6

3. ALGORITMO DE DIJKSTRA: TODOS LOS CAMINOS M NIMOS


Dado un grafo dirigido G = (V, A) (V es el conjunto de nodos y A es el conjunto de arcos) ponderado por p : V V R0, escribir un algoritmo que calcule los costes de los caminos m nimos entre cualquier par de nodos del grafo haciendo uso unicamente de algoritmos vistos en clase.

FI UPV: Curso 2009/2010

Pgina 6.42 a

EDA-6

3. ALGORITMO DE DIJKSTRA: TODOS LOS CAMINOS M NIMOS


Dado un grafo dirigido G = (V, A) (V es el conjunto de nodos y A es el conjunto de arcos) ponderado por p : V V R0, escribir un algoritmo que calcule los costes de los caminos m nimos entre cualquier par de nodos del grafo haciendo uso unicamente de algoritmos vistos en clase.
1 2 3 4 5

void TodosCaminosCortos (GrafoPonderado *G, MatrizDistancias &M) { for (u = 0; u < G->vertices; u++) M[u] = Dijkstra(G, u); // calcula la distancia // de u a todos los dems a }

Si el coste del algoritmo de Dijsktra es O(|V |2), entonces el coste temporal de este algoritmo es O(|V |3) y el coste espacial es O(|V |2). Para grafos dispersos, se puede obtener una implementacin ms cuidada para el o a algoritmo de Dijsktra de O((|V | + |A|) log |V |), por tanto el algoritmo propuesto ser O(|V |(|V | + |A|) log |V |). a

FI UPV: Curso 2009/2010

Pgina 6.43 a

EDA-6

4. FLUJO MAXIMO EN UN GRAFO

Una red de ujo G = (V, E) es un grafo dirigido en el cual cada arista (u, v) E tiene asociada una capacidad mxima c(u, v) 0. a Si una arista no pertenece a la red de ujo, entonces se supone que su capacidad mxima es 0. a Una red de ujo tiene dos nodos especiales denominados fuente y sumidero. Un ujo en una red de ujo es un conjunto de pesos no negativos de aristas que satisfacen las condiciones: Ningn peso es mayor que la capacidad de la arista u El ujo total que entra en un nodo es igual al ujo total que sale del nodo (excepto para los nodos fuente y sumidero).

FI UPV: Curso 2009/2010

Pgina 6.44 a

EDA-6

4. FLUJO MAXIMO EN UN GRAFO

Sea G = (V, E) una red de ujo con una fuente s y un sumidero t. Un ujo en G es un funcin f : V V R que cumple tres propiedades: o Restriccin de capacidad: u, v V, f (u, v) c(u, v) o Simetr inversa: u, v V, f (u, v) = f (v, u) a Conservacin de ujo: para todo u V {s, t}, o
vV

f (u, v) = 0.

El valor f (u, v) se denomina ujo del nodo u al nodo v. El valor de un ujo f (denotado como |f |) se dene como: |f | = vV f (s, v), es decir, el ujo total que sale de la fuente. Dada una red de ujo G con una fuente s y un sumidero t, el problema del ujo mximo consiste en encontrar un ujo de valor mximo. a a

FI UPV: Curso 2009/2010

Pgina 6.45 a

EDA-6

4. FLUJO MAXIMO EN UN GRAFO Aplicaciones

El problema del ujo mximo no slo es importante desde un punto de a o vista terico, sino que tiene aplicaciones prcticas en multitud de problemas o a de planicacin, asignacin de recursos, sirve de modelo para una variedad de o o problemas de programacin lineal, acoplamiento en grafos bipartidos, problemas o de conectividad, etc. Este problema est estrechamente relacionado con encontrar la cortadura a m nima entre s y t en el grafo.

FI UPV: Curso 2009/2010

Pgina 6.46 a

EDA-6

4. FLUJO MAXIMO EN UN GRAFO Cortadura m nima entre s y t


Una cortadura entre s y t en el grafo G=(V,A) es una particin (X, Y ) de o los vrtices del grafo (X Y = V, X Y = ), tal que s X y t Y . e La capacidad de una cortadura se dene: cap(X, Y ) =
uX,vY

c(u, v)

El ujo de s a t en G puede calcularse considerando unicamente las aristas que van de un vrtice de X a otro de Y . e Consecuentemente, para cualquier ujo f y cualquier cortadura (X, Y ) se cumple |f | cap(X, Y ). El teorema ujo mximo cortadura m a nima establece que esa desigualdad se alcanza para el ujo mximo. Es decir, f es un ujo mximo si y slo a a o si |f | = cap(X, Y ) para una cortadura (X, Y ) del grafo, y en tal caso esa cortadura tiene capacidad m nima.
FI UPV: Curso 2009/2010 Pgina 6.47 a

EDA-6

4. FLUJO MAXIMO EN UN GRAFO Algoritmos

Los algoritmos para encontrar el ujo mximo pueden dividirse en dos familias a en funcin de si mantienen o no la restriccin de conservacin de ujo: o o o Caminos de aumento Se basan en mantener un ujo vlido en todo momento. a Aumentan el ujo de s a t de manera iterativa. Partiendo de un ujo posible arbitrario (por ejemplo, ujo nulo) se busca un camino de s a t en un grafo residual que permita aumentar el ujo. Bajo ciertas condiciones se garantiza la terminacin del algoritmo. o Enviar preujo Se relajan las condiciones a cumplir durante el transcurso del algoritmo. Concretamente, se permite que el ujo neto en los vrtices pueda e ser positivo, si bien al nalizar el algoritmo el ujo debe cumplir la condicin o de conservacin de ujo. Se basan en enviar el exceso de ujo hacia el o sumidero asociando a cada vrtice una altura para controlar la direccin e o de env del exceso de ujo. o
FI UPV: Curso 2009/2010 Pgina 6.48 a

EDA-6

4. FLUJO MAXIMO EN UN GRAFO Algoritmo de Ford-Fulkerson


El algoritmo de Ford-Fulkerson, que data de 1962, es el primer algoritmo propuesto para resolver el problema del ujo mximo. Se basa en el concepto a de grafo residual. Dado un ujo f en un grafo G = (V, A), se dene el grafo residual Gf como aquel grafo con los mismos vrtices que G, arcos (u, v) tal que (u, v) A e o (v, u) A y capacidades cf (u, v) = c(u, v) f (u, v). Es decir, por cada arco del grafo G aparecen dos arcos en sentidos opuestos en el grafo residual. Un camino aumentado es un camino de s a t en el grafo residual Gf que pase por arcos con capacidad residual cf no nula.

FI UPV: Curso 2009/2010

Pgina 6.49 a

EDA-6

4. FLUJO MAXIMO EN UN GRAFO Algoritmo de Ford-Fulkerson


1 2 3 4 5 6 7 8 9 10 11 12

inicializar flujo f=0; construir grafo residual Gf asociado a f=0; maxflow = 0; while (existe camino de aumento de s a t en Gf) { delta = menor capacidad del camino de aumento; maxflow += delta; para cada arista (u,v) del camino de aumento hacer { c_f(u,v) -= delta; c_f(v,u) += delta; } } return maxflow;

FI UPV: Curso 2009/2010

Pgina 6.50 a

EDA-6

4. FLUJO MAXIMO EN UN GRAFO Algoritmo de Ford-Fulkerson


Se demuestra que si el algoritmo termina (si no existe ningun camino de aumento), el ujo devuelto es mximo. a El coste del algoritmo depende del coste de cada iteracin (buscar un camino o de aumento y recorrerlo para actualizar el grafo residual) y del nmero de u iteraciones. Si las capacidades son todas valores enteros, el algoritmo terminar y adems, a a por la propiedad de integridad, el ujo mximo ser un valor entero. Sin ms a a a informacin sobre los caminos utilizados, el nmero de pasos puede ser tan o u alto como la capacidad mxima de las aristas, con lo que el coste ser no a a polinmico con la talla del grafo. o

FI UPV: Curso 2009/2010

Pgina 6.51 a

EDA-6

4. FLUJO MAXIMO EN UN GRAFO Algoritmo de Edmonds-Karp


Edmonds y karp demostraron que si en el algoritmo de Ford-Fulkerson se utiliza el camino de aumento ms corto en cada iteracin, el algoritmo consigue a o mejores cotas asintticas: se vuelve polinmico con coste O(|V | |A|2). o o El algoritmo de Edmonds-Karp es tan simple como utilizar bsqueda primero u en anchura (BFS) para buscar el camino de aumento en el algoritmo de Ford-Fulkerson.

FI UPV: Curso 2009/2010

Pgina 6.52 a

También podría gustarte