Upload
dinhduong
View
215
Download
3
Embed Size (px)
Citation preview
Caminho mais curto a partir de um noAlgoritmos de Dijkstra e Bellman-Ford
Fernando Lobo
Algoritmos e Estrutura de Dados II
1 / 28
Caminho mais curto a partir de um no
I Input: Um grafo com pesos nos arcos G = (V ,E ), w : E → Re um no de partida s.
I Output: Caminho mais curto de s para todos os outros nos dografo.
I O peso (ou distancia ou custo) de um caminho e igual aosomatorio dos pesos dos arcos que constituem o caminho, ou∞ se nao existir caminho.
I Formalmente, seja p o caminho v0 ; vk = 〈v0, v1, . . . , vk〉.
peso(p) =k∑
i=1
w(vi−1, vi )
2 / 28
O problema tem subestrutura optima
I Qualquer subcaminho de um caminho mais curto, tambem eum caminho mais curto.
I Demonstracao: Por reducao ao absurdo.
I Seja p um caminho mais curto de u para v .p passa pelos nos x e y (ver figura).
I peso(p) = peso(Pux) + peso(Pxy ) + peso(Pyv )
3 / 28
I Vamos mostrar que Pxy e forcosamente um caminho maiscurto de x para y .
I Suponhamos que existe um caminho estritamente mais curtoP ′xy entre x e y . Isto e, peso(P ′xy ) < peso(Pxy )
I Entao poderıamos construir o caminho p′ do seguinte modo:
peso(p′) = peso(Pux) + peso(P ′xy ) + peso(Pyv )
< peso(Pux) + peso(Pxy ) + peso(Pyv )
= peso(p)
I =⇒ p nao e um caminho mais curto. Uma contradicao.
4 / 28
Relaxamento de arcos
I Os algoritmos que vamos ver usam a tecnica de relaxamento.
I Cada no v mantem um atributo, v .d , que nos da um limitesuperior do peso de um caminho mais curto de s para v .
I A tecnica de relaxamento para um arco (u, v) consiste emtestar se e possıvel melhorar o caminho mais curto para vpassando por u, e em caso afirmativo, actualizar v .d .
5 / 28
Pseudocodigo
Relax(u, v ,w)
if v .d > u.d + w(u, v)v .d = u.d + w(u, v)v .π = u
Ao inıcio, o atributo v .d = ∞ para todos os nos excepto para ono de partida s, em que s.d = 0.
Initialize-Single-Source(G , s)
for each v ∈ G .Vv .d = ∞v .π = nil
s.d = 0
6 / 28
Algoritmo de Dijkstra
I Restricao: Os pesos nao podem ser negativos.
I Parecido com BFS (e tambem com Algoritmo de Prim).
I Usa uma fila com prioridade em vez de uma fila FIFO.
I Chave (prioridade) de um no na fila e o limite superior docusto do caminho mais curto desde o no de origem.
I O algoritmo mantem dois conjuntos de nos:
I S = nos para os quais ja determinamos o caminho mais curto.
I Q = V − S (nos que ainda estao na fila).
7 / 28
Pseudocodigo
Dijkstra(G ,w , s)
Initialize-Single-Source(G , s)S = ∅Q = G .Vwhile Q 6= ∅
u = Extract-Min(Q)S = S ∪ {u}for each v ∈ G .Adj [u]
Relax(u, v ,w)
I No final do algoritmo, v .d tem o peso (custo) do caminhomais curto do no de origem s ate v .
I Tal como no BFS, o atributo π permite-nos obter o caminhomais curto.
8 / 28
2a iteracao: no C sai da fila
3a iteracao: no E sai da fila
11 / 28
4a iteracao: no B sai da fila
12 / 28
5a iteracao: no D sai da fila
13 / 28
Complexidade do Algoritmo de Dijkstra
I Inicializacao: Θ(V )
I Ciclo while e executado |V | vezes.
I |V | Extract-Mins
I Todos os arcos do grafo sao visitados. Para cada um, hapotencialmente um Decrease-Key.
I =⇒ Θ(V · TExtract-Min + E · TDecrease-Key)
I Se a fila com prioridade for implementada com um heapbinario (ver materia de AED-I), obtemos:
I TExtract-Min = O(lg V )
I TDecrease-Key = O(lg V )
14 / 28
Complexidade do Algoritmo de Dijkstra
I Total = O(V lg V + E lg V ) = O ((V + E ) lg V )
I Igual a complexidade do Algoritmo de Prim.
I Consegue-se melhorar a complexidade implementando a filacom prioridade com heaps de Fibonacci.
15 / 28
Algoritmo de Bellman-Ford
I O Algoritmo de Dijkstra so funciona se todas as arestas dografo tiverem pesos ≥ 0.
I Agora vamos ver um algoritmo que tambem funciona no casode haver arestas com < 0.
16 / 28
Exemplo
I Caminho mais curto de A para D tem peso -1.A → B → E → D
I O algoritmo de Dijkstra daria: A → B → D (com peso 1)
17 / 28
Algumas observacoes
I Caminho mais curto nao pode ter mais do que |V | − 1 arcos.
I Caso contrario teria de haver forcosamente um ciclo nocaminho mais curto.
I ciclo com peso < 0 =⇒ nao existe caminho mais curto.
I ciclo com peso > 0 nunca pode fazer parte de um caminhomais curto.
I ciclo com peso = 0 pode ser sempre removido.
18 / 28
Algoritmo de Bellman-Ford
I Algoritmo de Bellman-Ford tira partido das observacoesanteriores.
I Tal como o Algoritmo de Dijkstra, tambem usa a tecnica derelaxamento dos arcos.
I E conceptualmente mais simples que o Algoritmo de Dijkstra,mas a complexidade temporal e maior.
19 / 28
Pseudocodigo
Bellman-Ford(G ,w , s)
Initialize-Single-Source(G , s)for i = 1 to |G .V | − 1
for each (u, v) ∈ G .ERelax(u, v ,w)
for each (u, v) ∈ G .Eif v .d > u.d + w(u, v)
return falsereturn true
———————————————
I Retorna true se e so se o grafo nao tiver um ciclo com pesonegativo que possa ser alcancado a partir do no de origem s.
I Complexidade: Θ(V · E )
20 / 28
Exemplo de execucao. No de origem: A
21 / 28
I Ordem pela qual o algoritmo processa os arcos:#1 → (B,E)#2 → (D,B)#3 → (B,D)#4 → (A,B)#5 → (A,C)#6 → (D,C)#7 → (B,C)#8 → (E,D)
I Qualquer outra ordem servia.
22 / 28
A B C D E
i = 1 0 ∞ ∞ ∞ ∞0 -1 ∞ ∞ ∞ // A → B0 -1 4 ∞ ∞ // A → C0 -1 2 ∞ ∞ // B → C
i = 2 0 -1 2 ∞ 2 // B → E0 -1 2 1 2 // B → D0 -1 2 -1 2 // E → D
i = 3
i = 4
Neste caso nem era necessario fazermos a iteracao i = 4 porque naiteracao i = 3 ja nao foi possıvel relaxar qualquer arco.
23 / 28
Correccao do algoritmo
I Definicao: δ(s, v) e o peso de um caminho mais curto de spara v .
δ(s, v) =
{min{w(p) : s ; v}∞ se nao existir caminho de s para v
I Se G = (V ,E ) nao tiver ciclos com peso negativo, entao aoterminar a execucao do algoritmo Bellman-Ford,v .d = δ(s, v), ∀v∈V
24 / 28
Demonstracao
I Seja v ∈ V um qualquer no do grafo. Consideremos umcaminho mais curto p de s para v .
I Como p e um caminho mais curto,
δ(s, vi ) = δ(s, vi−1) + w(vi−1, vi )
I Porque? Devido a subestrutura optima.
25 / 28
Demonstracao (cont.)
I Apos a inicializacao,
v0.d = 0 = δ(s, v0)
e nunca mais vai ser alterado. Porque? Porque isso implicariahaver ciclos com peso negativo.
I Apos a 1a iteracao (i = 1): v1.d = δ(s, v1)
I Apos a 2a iteracao (i = 2): v2.d = δ(s, v2)
I . . .
I Apos a ka iteracao (i=k): vk .d = δ(s, vk)
26 / 28
Demonstracao (cont.)
I Como G nao tem ciclos com peso negativo, o caminho maiscurto p e um caminho simples e nao podera ter mais do que|V | − 1 arcos (daı o ciclo exterior ser executado |V | − 1vezes).
27 / 28
Corolario
I Se no final das |V | − 1 iteracoes existir algum v .d 6= δ(s, v),entao e porque existe um ciclo com peso negativo em G quepode ser alcancado a partir de s.
I =⇒ nao existe caminho mais curto de s para v .
28 / 28