CI2613

Anuncio
CI2613: Algoritmos y Estructuras III
Caminos de costo mı́nimo en grafos
Blai Bonet
Universidad Simón Bolı́var, Caracas, Venezuela
Enero-Marzo 2015
c 2014 Blai Bonet
Caminos entre todos los pares de vértices
Caminos entre todos los pares de vértices
Estamos interesados en calcular distancias y caminos más cortos entre
todos los pares de vértices
La salida de un algoritmo para calcular las distancias y caminos más
cortos entre todos los pares de vértices es:
– una matriz D de distancias donde la entrada dij es δ(i, j)
Podemos ejecutar Bellman-Ford desde cada vértice s en un tiempo
O(V 2 E), ya que Bellman-Ford requiere O(V E) unidades de tiempo
– una matrix Π de predecesores tal que el grafo Gi = (Vi , Ei ) con
Vi = {j : πij 6= null} ∪ {i} y Ei = {(πij , j) : j ∈ Vi \ {i}} es un
árbol de caminos más cortos relativo al vértice i
Con pesos no-negativos, se utiliza Dijkstra en lugar de Bellman-Ford.
El tiempo dependerá de la implementación de la cola de prioridad:
– Heap de Fibonacci: O(V E + V 2 log V ) unidades de tiempo
Los algoritmos asumen un grafo dado por una matriz W de pesos:
wij es el peso de la arista (i, j) (con wjj = 0 y wij = ∞ si no existe
la arista)
El heap de Fibonacci hace diferencia cuando O(V 2 log V ) es “menor”
a O(V E log V ); i.e. cuando |V | = o(E)
Esto no causa problema ya que el algoritmo debe invertir tiempo
Ω(V 2 ) para generar la salida
– Heap binario: O(V E log V ) unidades de tiempo
c 2014 Blai Bonet
CI2613
CI2613
c 2014 Blai Bonet
CI2613
Primer algoritmo: Programación dinámica
Primer algoritmo: Programación dinámica
(m)
Sea `ij el costo del mejor camino del vértice i al vértice j que
tiene a lo sumo m aristas
(0)
`ij =
Observe:
(m)
`ij
0 si i = j
∞ si i 6= j
= min
(m−1)
`ij
,
=
El mejor camino con a lo sumo m aristas es: el mejor camino con a lo
sumo m − 1 aristas ó un camino con m aristas
(m)
`ij
= min
(m−1)
`ij
,
(m−1)
min `ik
1≤k≤n
(n−1)
+ wkj
(m)
CI2613
=
min
1≤k≤n
(m−1)
`ik
3
4
5
6
7
8
9
CI2613
El algoritmo computa las matrices L(1) , L(2) , L(3) , . . . , L(n−1)
+ wkj
2
2
+ wkj
Primer algoritmo: Pseudocódigo
1
1
c 2014 Blai Bonet
Primer algoritmo: Subrutina central
El algoritmo computa matrices L(1) , L(2) , L(3) , . . . , L(n−1) tal que
(m)
L(m) = (`ij )
Por definición, δ(i, j) = `ij
= `ij , para m > n − 1, ya que el
mejor camino tiene ≤ n − 1 aristas (si no hay ciclos de costo negativo)
(m)
`ij
(m−1)
`ik
+ wkj
ya que wjj = 0 por definición
c 2014 Blai Bonet
min
1≤k≤n
(m−1)
min `
1≤k≤n ik
3
Matriz Extender-Caminos(L, W):
n = nrows(L)
L’ = new Matriz(n,n)
for i = 1 to n
for j = 1 to n
L’[i,j] = ∞
for k = 1 to n
L’[i,j] = min { L’[i,j], L[i,k] + W[k,j] }
return L’
4
5
6
void Calcular-Distancias(W):
n = nrows(W)
L(1) = W
for m = 2 to n - 1
L(m) = Extender-Caminos(L(m-1), W)
return L(n-1)
Calcular-Distancias
toma tiempo Θ(n4 )
Θ(n4 ) iguala el tiempo Θ(V 2 E) para n corridas de Bellman-Ford en
grafos densos (i.e. |E| = Θ(V 2 ))
Extender-Caminos
c 2014 Blai Bonet
toma tiempo Θ(n3 )
CI2613
c 2014 Blai Bonet
CI2613
Primer algoritmo: Ejemplo
Relación con multiplicación de matrices
hola

2
3
4
1
L(1)
8
2
3
−5
−4
7
1
(2)
5
L(4)

0
3

= 
7
2
8
6
1
0
4
−1
5
L
4
−3
−4
0
−5
1
2
1
5
0
6

−4
−1

3

−2
0
0
∞

= 
∞
2
∞
3
0
4
∞
∞

3
0
4
−1
∞
0
3

= 
∞
2
8

L(3)
0
3

= 
7
2
8
3
0
4
−1
5
8
∞
0
−5
∞
8
−4
0
−5
1
−3
−4
0
−5
1
∞
1
∞
0
6

−4
7

∞

∞
0
2
1
5
0
6

−4
7 

11 

−2
0
2
1
5
0
6
La operación implementada por Extender-Caminos(A,
relacionada con la multiplación de matrices
Defina A ⊗ B = Extender-Caminos(A,
matrices A, B de dimensión n × n
B)
B)
está
para cualquier par de
Lema
Para cualquier i, j ≥ 0, L(i) ⊗ L(j) = L(i+j)
Prueba: por inducción en j (para cualquier i fijo)
Base j = 0: L(i) ⊗ L(0) = L(i) (ejercicio)

−4
−1

3

−2 
0
Caso j > 0:
L(i) ⊗ L(j) = L(i) ⊗ (L(j−1) ⊗ W ) = (L(i) ⊗ L(j−1) ) ⊗ W
= L(i+j−1) ⊗ W = L(i+j)
c 2014 Blai Bonet
CI2613
c 2014 Blai Bonet
Relación con multiplicación de matrices
Segundo algoritmo: Pseudocódigo
El algoritmo computa las matrices L(1) , L(2) , L(4) , . . . , L(2m) con
2m > n − 1
Corolario
Para cualquier m ≥ 0, L(2m) = L(m) ⊗ L(m)
1
2
Por ejemplo,
3
4
(2)
L
(1)
=L
⊗L
(1)
CI2613
=W ⊗W
5
6
L(4) = L(2) ⊗ L(2) = W ⊗ W ⊗ W ⊗ W
7
8
bool Calcular-Distancias-II(W):
n = nrows(W)
L(1) = W
m = 1
while m < n - 1
L(2m) = Extender-Caminos(L(m), L(m))
m = 2m
return L(m/2)
L(8) = L(4) ⊗ L(4) = W ⊗ W ⊗ W ⊗ W ⊗ W ⊗ W ⊗ W ⊗ W
L(16) = L(8) ⊗ L(8) = W ⊗ · · · ⊗ W
c 2014 Blai Bonet
Calcular-Distancias-II
mejor a Θ(n4 )
CI2613
c 2014 Blai Bonet
toma tiempo Θ(n3 log n) que es mucho
CI2613
Computar caminos más cortos
1
2
3
4
5
6
7
8
9
Algoritmo de Floyd-Warshall
Hemos visto como computar la matriz D = L(n−1) de distancias en
un grafo con n vertices
También basado en programación dinámica pero con una
formulación diferente
Caminos más cortos entre todos los pares de vértices se pueden
calcular en tiempo Θ(n3 ) a partir de D de la siguiente forma:
Floyd-Warshall toma tiempo Θ(n3 ) que es una mejora sobre
Θ(n3 log n)
En lugar de considerar caminos de i a j con a lo sumo k aristas,
F-W considera caminos de i a j que pasan sólo sobre {1, 2, . . . , k}
bool Calcular-Caminos(D, W):
n = nrows(W)
Π = new Matriz(n,n)
for i = 1 to n
for j = 1 to n
for k = 1 to n
if D[i,j] == D[i,k] + W[k,j]
Π[i,j] = k
return Π
Defina:
(k)
dij = costo mejor camino de i a j que pasa sólo sobre {1, . . . , k}
(n)
(0)
Por definición, dij = δ(i, j) y dij = wij
c 2014 Blai Bonet
CI2613
c 2014 Blai Bonet
Programación dinámica de Floyd-Warshall
CI2613
Floyd-Warshall: Pseudocódigo
(m)
Se computan las matrices D(m) = (dij ) para m = 1, 2, . . . , n
Consider un mejor camino de i a j que pasa sobre {1, 2, . . . , k}.
Existen dos posibilidades:
(
(k)
dij
– el camino no visita el vértice k (i.e. pasa sobre {1, 2, . . . , k − 1}), ó
=
wij
si k = 0
(k−1) (k−1)
(k−1) min dij , dik
+ dkj
si k > 0
– el camino visita el vértice k
1
Como todo camino óptimo no tiene ciclos, en el segundo caso se
visita k una sóla vez
2
3
4
5
(k)
dij
=

w

 ij
7
8

 min
6
si k = 0
(k−1)
dij ,
(k−1)
dik
+
(k−1)
dkj
9
si k > 0
Matriz Floyd-Warshall(W):
n = nrows(L)
D(0) = W
for k = 1 to n
D(k) = new Matriz(n,n)
for i = 1 to n
for j = 1 to n
D(k) = min { D(k-1)[i,j], D(k-1)[i,k] + D(k-1)[k,j] }
return D(n)
Floyd-Warshall
c 2014 Blai Bonet
CI2613
c 2014 Blai Bonet
toma tiempo Θ(n3 )
CI2613
Floyd-Warshall: Ejemplo
Floyd-Warshall: Ejemplo
hola
hola
2
3
1
8
2
3
0
4
∞
∞
8
∞
0
−5
∞
∞
1
∞
0
6

−4
7

∞

∞
0
3
D(0)

0
∞

= 
∞
2
∞
3
0
4
5
∞
8
∞
0
−5
∞
∞
1
∞
0
6

−4
7 

∞

−2
0

3
0
4
5
∞
8
∞
0
−5
∞
4
1
5
0
6
2
3
7
5
6
4
8
2
D(1)
D(2)
0
∞

= 
∞
2
∞
7
5

−4
7

11 

−2
0
3
D(3)
1
6
4
D(4)
D(5)
CI2613
c 2014 Blai Bonet
0
∞

= 
∞
2
∞
3
0
4
−1
∞
8
∞
0
−5
∞
4
1
5
0
6

−4
7

11 

−2
0
−5
−4
1

4
1
−5
−4
c 2014 Blai Bonet
0
∞

= 
∞
2
∞

4

3
0
4
−1
5
−1
−4
0
−5
1
4
1
5
0
6

−4
−1

3

−2 
0

1
0
4
−1
5
−3
−4
0
−5
1
2
1
5
0
6

−4
−1

3

−2
0
0
3

= 
7
2
8
0
3

= 
7
2
8
CI2613
Descargar