Análise e Síntese de Algoritmos Contexto

Propaganda
Análise e Síntese de Algoritmos
Caminhos Mais Curtos para Todos os Pares
CLRS, Cap. 25
Contexto
• Algoritmos Elementares em Grafos
(CLR, Cap. 22)
– BFS & DFS
– Ordenação Topológica & SCCs
• Árvores Abrangentes de Menor Custo (CLR, Cap. 23)
– Algoritmos de Borůvka, Kruskal e Prim
• Caminhos mais curtos com fonte única (CLR, Cap. 24)
– Algoritmos de Dijkstra e Bellman-Ford
• Caminhos mais curtos entre todos os pares (CLR, Cap. 25)
– Solução Recursiva, Algoritmos de Floyd-Warshall e Johnson
2006/2007
Análise e Síntese de Algoritmos
2
1
Resumo
• Caminhos Mais Curtos entre Todos os Pares (APSPs)
– Definições
– Soluções recursivas
• Algoritmo de Floyd-Warshall
– Fecho Transitivo
– Algoritmo de Johnson
2006/2007
Análise e Síntese de Algoritmos
3
Caminhos Mais Curtos entre Todos
os Pares (APSPs) — Observações
• Encontrar caminhos mais curtos entre todos os pares
de vértices
• Se pesos não negativos
– Utilizar algoritmo de Dijkstra, assumindo cada vértice como
fonte: O(V E lg V)
(que é O(V3 lg V) se grafo é denso)
• Se pesos negativos
– Utilizar algoritmo de Bellman-Ford, assumindo cada vértice
como fonte: O(V2E)
(que é O(V4) se grafo é denso)
• Objectivo: Encontrar algoritmos mais eficientes
2006/2007
Análise e Síntese de Algoritmos
4
2
APSPs — Definições
• Representação: utilização de matriz de adjacências
• Pesos dos arcos: matriz (n x n) W = (wij)
se i = j
$0
!
w ij = #peso do arco (i, j) se i & j e (i, j)( E
!'
se i & j e (i, j)% E
"
• Representação dos caminhos mais curtos: matriz (n x
n) D = (dij)
– dij é o peso do caminho mais curto entre os vértices i e j
• dij = δ(vi,vj)
2006/2007
Análise e Síntese de Algoritmos
5
APSPs — Definições
• Representação de caminhos mais curtos
– Matriz de predecessores ∏ = (πij)
– πij:
• NIL: se i = j ou não existe caminho de i para j
• Caso contrário: predecessor de j num caminho mais
curto de i para j
– Sub-grafo de predecessores de G para i, Gπ, i = (Vπ, i, Eπ, i)
V#,i = {j $ V : #ij " NIL}! {}
i
E #,i = {(#ij , j): j " V#,i ! {i}}
• Sub-grafo induzido pela linha i de ∏
– Exemplo
2006/2007
Análise e Síntese de Algoritmos
6
3
APSPs — Solução Recursiva
• Sub-caminhos de caminhos mais curtos são
também caminhos mais curtos
• Peso mínimo em caminho de vértice i para vértice j
que contém não mais do que m arcos: d(ijm )
– Com m = 0, existe caminho de i para j se e só se i = j
#0 se i = j
dij(0 ) = "
!% se i $ j
– Para m ≥ 1,
{
}
dij(m ) = min dij(m !1), min{dik(m !1) + w kj } = min{dik(m !1) + w kj }
1"k "n
1"k "n
wjj = 0
2006/2007
Análise e Síntese de Algoritmos
7
APSPs — Solução Recursiva
• Calcular sequência de matrizes D(1), …, D(n-1), onde
– D(n-1) contém os pesos dos caminhos mais curtos
– D(1) = W
Extend-Shortest-Paths(D,W)
n = rows[W]
D’: matriz (n x n)
for i = 1 to n
for j = 1 to n
dij' = !
for k = 1 to n
dij' = min(dij' , dik + w kj )
return D’
• Complexidade: Θ(n3) p/ cada matriz; Total: Θ(n4)
2006/2007
Análise e Síntese de Algoritmos
8
4
APSPs — Solução Recursiva
• Genericamente: calcular D(i) em função de D(i-1) (e de W)
• Complexidade para cálculo de D(n): Θ(n4)
• OBS: é possível melhorar complexidade reduzindo
número de matrizes calculadas: Θ(n3lg n)
– A cada iteração, calcular D(2i) em função de D(i) e de D(i)
2006/2007
Análise e Síntese de Algoritmos
9
APSPs — Algoritmo de Floyd-Warshall
• Caracterização de um caminho mais curto
– Vértices intermédios de caminho p = 〈v1,v2,…,vk〉, {v2,…,vk-1}
• Considerar todos os caminhos entre i e j com
vértices intermédios retirados do conjunto {1,…,k} e
seja p um caminho mais curto (p é simples)
– Se k não é vértice intermédio de p, então todos os vértices
intermédios de p estão em {1,…,k-1}
– Se k é vértice intermédio de p, então existem caminhos p1 e
p2, respectivamente de i para k e de k para j com vértices
intermédios em {1,…,k}
• k não é vértice intermédio de p1 e de p2
• p1 e p2 com vértices intermédios em {1,…,k-1}
2006/2007
Análise e Síntese de Algoritmos
10
5
APSPs — Algoritmo de Floyd-Warshall
p1
k
i
p2
j
Vértices entre
1 e k-1
• Formulação
se k = 0
#w ij
dij(k ) = "
(k %1) (k %1)
(k %1)
!min(dij , dik + dkj ) se k $ 1
Vértices entre
1ek
2006/2007
Análise e Síntese de Algoritmos
11
APSPs — Algoritmo de Floyd-Warshall
Floyd-Warshall(W)
n = rows[W]
D(0) = W
for k = 1 to n
for i = 1 to n
for j = 1 to n
dij(k ) = min(dij(k !1), dik(k !1) + dkj(k !1) )
(n)
return D
• Complexidade: Θ(n3)
• Exemplo
2006/2007
Análise e Síntese de Algoritmos
12
6
Fecho Transitivo de um Grafo Dirigido
• Dado um grafo G = (V, E) dirigido, o fecho transitivo
é definido por G* = (V, E*) tal que,
E*={(i, j): existe caminho de i para j em G}
• Algoritmo:
– Atribuir a cada arco peso 1 e utilizar algoritmo de FloydWarshall
• Se dij ≠ ∞, então (i, j) ∈ E*
• Complexidade: Θ(n3)
2006/2007
Análise e Síntese de Algoritmos
13
Fecho Transitivo de um Grafo Dirigido
• Outro algoritmo:
– Substituir operações min e + por ∨ e ∧, respectivamente
– Se existe caminho de i para j com todos os vértices
intermédios em {1,2,…,k}, t ij(k ) = 1
– Caso contrário, t ij(k ) = 0
– Formulação:
#0 se i & j e (i, j)% E
t ij(0 ) = "
!1 se i = j ou (i, j)$ E
– Complexidade: Θ(n3)
– Exemplo
2006/2007
t ij(k ) = t ij(k $1) # (t ik(k $1) " t kj(k $1) ) se k ! 1
(mas constantes menores)
Análise e Síntese de Algoritmos
14
7
Fecho Transitivo de um Grafo Dirigido
Transitive-Closure(G)
n = |V[G]|
for i = 1 to n
for j = 1 to n
if i = j or (i, j) ∈ E
t ij(0 ) = 1
else
t ij(0 ) = 0
for k = 1 to n
for i = 1 to n
for j = 1 to n
t ij(k ) = t ij(k !1) # (t ik(k !1) " t kj(k !1) )
(n)
return T
2006/2007
Análise e Síntese de Algoritmos
15
APSPs — Algoritmo de Johnson
• Utiliza algoritmos de Dijkstra e de Bellman-Ford
• Baseado em re-pesagem dos arcos
– Se arcos com pesos não negativos, utilizar Dijkstra para
cada vértice
– Caso contrário, calcular novo conjunto de pesos não
negativos w’, tal que
• Um caminho mais curto de u para v com função w é
também caminho mais curto com função w’
• Para cada arco (u, v) o peso w’(u, v) é não negativo
2006/2007
Análise e Síntese de Algoritmos
16
8
APSPs — Algoritmo de Johnson
• Dado G = (V, E), com função de pesos w e de repesagem h: V → R, seja w’(u, v) = w(u, v) + h(u) - h(v)
• Seja p = 〈v0,v1,…,vk 〉. Então w(p) = δ(v0 , vk) se e só se
w’(p) = δ’(v0, vk) = δ(v0, vk) + h(v0) - h(vk )
– Existe ciclo negativo com w se e só se existe ciclo negativo
com w’
w ' (p ) = w (p ) + h(v 0 ) ! h(v k )
w ' (p ) =
k
" w ' (v i!1, v i )
i =1
k
=
" (w (v i!1, v i )+ h(v i!1 )! h(v i ))
i =1
k
=
" w (v i!1, v i )+ h(v 0 )! h(v k ) = w (p)+ h(v 0 )! h(v k )
i =1
2006/2007
Análise e Síntese de Algoritmos
17
APSPs — Algoritmo de Johnson
w (p ) = !(v 0 , v k ) " w ' (p ) = !' (v 0 , v k )
Hipótese: existe pz, caminho mais curto de v0 para vk com w’
Então: w ' (p z ) < w ' (p )
w (p z ) + h(v 0 ) ! h(v k ) = w ' (p z ) < w ' (p ) = w (p ) + h(v 0 ) ! h(v k )
O que implica w (p z ) < w (p )
Mas p é caminho mais curto com w; contradição !
OBS: Para quaisquer caminhos p1, p2 entre v0 e vk, verifica-se
w(p1) < w(p2) ⇔ w’(p1) < w’(p2)
2006/2007
Análise e Síntese de Algoritmos
18
9
APSPs — Algoritmo de Johnson
w (p ) = !(v 0 , v k ) " w ' (p ) = !' (v 0 , v k )
Semelhante:
Admitir pz como caminho mais curto de v0 para vk com w
(ou considerar observação anterior)
Existe ciclo negativo com w se e só se existe com w’
c = " v 0 , v 1,K, v k !; v 0 = v k ; w (c ) < 0
w ' (c ) = w (c ) + h(v 0 ) ! h(v k ) = w (c )
∴Caminhos mais curtos e ciclos negativos
inalteráveis com mudanças na função de pesos
w’(u, v) = w(u, v) + h(u) - h(v)
2006/2007
Análise e Síntese de Algoritmos
19
APSPs — Algoritmo de Johnson
• Dado G = (V, E), criar G’ = (V’,E’):
– V’ = V ∪ { s }
– E’ = E ∪ { (s, v) : v ∈ V }
– w(s, v) = 0
(∀ v ∈ V, atingível a partir de s)
• Com ciclos negativos:
– Detectados com algoritmo de Bellman-Ford aplicado a G’ !
• Sem ciclos negativos:
– Definir:
– Dado que:
– Verifica-se:
2006/2007
h(v) = δ(s, v)
h(v) ≤ h(u) + w(u, v)
w’(u, v) = w(u, v) + h(u) - h(v) ≥ 0 !
Análise e Síntese de Algoritmos
24.10
20
10
APSPs — Algoritmo de Johnson
• Executar Dijkstra para todo o u ∈ V
– Cálculo de δ’(u,v), para u ∈ V
– Mas também,
• δ’(u,v) = δ(u, v) + h(u) - h(v)
• δ(u,v) = δ’(u, v) + h(v) - h(u)
2006/2007
Análise e Síntese de Algoritmos
21
APSPs — Algoritmo de Johnson
Johnson(G)
Representar G’
if Bellman-Ford(G’,w,s) = FALSE
print “Indicar ciclo negativo”
else
atribuir h(v) = δ(s, v), calculado com Bellman-Ford
calcular w’(u,v) = w(u,v) + h(u) - h(v) para cada arco (u,v)
foreach v ∈ V[G]
executar Dijkstra(G,w’,v); calcular δ’(u, v)
duv = δ’(u, v) + h(v) - h(u)
return D
2006/2007
Análise e Síntese de Algoritmos
22
11
APSPs — Algoritmo de Johnson
• Complexidade:
– Bellman-Ford: O(V E)
– Executar Dijkstra para cada vértice: O(V (V + E) lg V)
• Assumindo amontoado (heap) binário
– Total: O(V (V + E) lg V)
• Útil para grafos esparsos
• Exemplo
2006/2007
Análise e Síntese de Algoritmos
23
Revisão
• Caminhos Mais Curtos entre Todos os Pares (APSPs)
–
–
–
–
–
Definições
Solução recursiva
Algoritmo de Floyd-Warshall
Fecho Transitivo
Algoritmo de Johnson
• A seguir:
– Fluxos máximos em grafos
2006/2007
Análise e Síntese de Algoritmos
(CLR, Cap. 26)
24
12
Download