DAA - caminhos mais curtos
Algoritmo de Dijkstra
O algoritmo de Dijkstra resolve o problema de caminhos mais curtos de fonte única em um grafo direcionado ponderado G = (V, E) , onde todas as arestas são não negativas (ou seja, w (u, v) ≥ 0 para cada aresta (u, v ) Є E ).
No algoritmo a seguir, usaremos uma função Extract-Min(), que extrai o nó com a menor chave.
Algorithm: Dijkstra’s-Algorithm (G, w, s)
for each vertex v Є G.V
v.d := ∞
v.∏ := NIL
s.d := 0
S := Ф
Q := G.V
while Q ≠ Ф
u := Extract-Min (Q)
S := S U {u}
for each vertex v Є G.adj[u]
if v.d > u.d + w(u, v)
v.d := u.d + w(u, v)
v.∏ := u
Análise
A complexidade deste algoritmo é totalmente dependente da implementação da função Extract-Min. Se a função extract min for implementada usando busca linear, a complexidade deste algoritmo éO(V2 + E).
Neste algoritmo, se usarmos min-heap em que Extract-Min() função funciona para retornar o nó de Q com a menor chave, a complexidade desse algoritmo pode ser reduzida ainda mais.
Exemplo
Vamos considerar o vértice 1 e 9como vértice inicial e de destino, respectivamente. Inicialmente, todos os vértices exceto o vértice inicial são marcados por ∞ e o vértice inicial é marcado por0.
Vértice | Inicial | Etapa 1 V 1 | Etapa 2 V 3 | Etapa 3 V 2 | Etapa 4 V 4 | Etapa 5 V 5 | Etapa 6 V 7 | Etapa 7 V 8 | Etapa 8 V 6 |
---|---|---|---|---|---|---|---|---|---|
1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
2 | ∞ | 5 | 4 | 4 | 4 | 4 | 4 | 4 | 4 |
3 | ∞ | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 |
4 | ∞ | ∞ | ∞ | 7 | 7 | 7 | 7 | 7 | 7 |
5 | ∞ | ∞ | ∞ | 11 | 9 | 9 | 9 | 9 | 9 |
6 | ∞ | ∞ | ∞ | ∞ | ∞ | 17 | 17 | 16 | 16 |
7 | ∞ | ∞ | 11 | 11 | 11 | 11 | 11 | 11 | 11 |
8 | ∞ | ∞ | ∞ | ∞ | ∞ | 16 | 13 | 13 | 13 |
9 | ∞ | ∞ | ∞ | ∞ | ∞ | ∞ | ∞ | ∞ | 20 |
Portanto, a distância mínima do vértice 9 do vértice 1 é 20. E o caminho é
1 → 3 → 7 → 8 → 6 → 9
Este caminho é determinado com base nas informações do predecessor.
Algoritmo Bellman Ford
Este algoritmo resolve o problema do caminho mais curto de fonte única de um gráfico direcionado G = (V, E)em que os pesos das bordas podem ser negativos. Além disso, este algoritmo pode ser aplicado para encontrar o caminho mais curto, caso não exista nenhum ciclo de ponderação negativa.
Algorithm: Bellman-Ford-Algorithm (G, w, s)
for each vertex v Є G.V
v.d := ∞
v.∏ := NIL
s.d := 0
for i = 1 to |G.V| - 1
for each edge (u, v) Є G.E
if v.d > u.d + w(u, v)
v.d := u.d +w(u, v)
v.∏ := u
for each edge (u, v) Є G.E
if v.d > u.d + w(u, v)
return FALSE
return TRUE
Análise
O primeiro for loop é usado para inicialização, que é executado em O(V)vezes. Nas próximasfor loop é executado |V - 1| passa pelas bordas, o que levaO(E) vezes.
Portanto, o algoritmo Bellman-Ford é executado em O(V, E) Tempo.
Exemplo
O exemplo a seguir mostra como o algoritmo Bellman-Ford funciona passo a passo. Este gráfico tem uma borda negativa, mas não tem nenhum ciclo negativo, portanto, o problema pode ser resolvido usando esta técnica.
No momento da inicialização, todos os vértices exceto a fonte são marcados por by e a fonte é marcada por 0.
Na primeira etapa, todos os vértices acessíveis da fonte são atualizados por custo mínimo. Portanto, vérticesa e h são atualizados.
Na próxima etapa, vértices a, b, f e e são atualizados.
Seguindo a mesma lógica, nesta etapa os vértices b, f, c e g são atualizados.
Aqui, vértices c e d são atualizados.
Portanto, a distância mínima entre o vértice s e vértice d é 20.
Com base nas informações do predecessor, o caminho é s → h → e → g → c → d