Já vimos que a busca em largura é capaz de encontrar a menor distância de um certo nó para qualquer outro nó para grafos não ponderados
E se areastes tiverem peso?
Problema Dados um grafo G=(V,E), uma função w de peso nas arestas e um vértice s∈V(G), calcular a distância mínima distGw(s,v) para todo v∈V(G).
Em outras palavras, queremos encontrar a distância mínima a partir de uma fonte s qualquer do grafo para todos os outros nós do grafo
Afirmação: Um subcaminho de um caminho mais curto também é um caminho mais curto
Afirmação: Um subcaminho de um caminho mais curto também é um caminho mais curto
Afirmação: Um subcaminho de um caminho mais curto também é um caminho mais curto
Afirmação: Um subcaminho de um caminho mais curto também é um caminho mais curto
O algoritmo de Dijkstra resolve o problema, e os pesos das areastas forem todos positivos
A distância v.distance para os nós v∈G é inicializada com ∞ e para a fonte é inicializada 0
Algoritmo guloso: a cada etapa descobre a menor distância para um novo vértice u, e "relaxa" a distância para os demais
Usamos um apontador para o predecessor de cada nó para armezar o menor caminho, além da menor distância
Podemos usar uma Heap para encontrar o vértice de menor distância mais rapidamente.
A Heap armazena os nós, de acordo com a distância conhecida até o momento.
Ideia básica:
Para melhorar o desempenho, podemos usar programação dinâmica!
Como podemos utilizar as distância d(k−1) calculadas na iteração k−1 para calcular a distância d(k) da iteração k?
No passo k, d(k) armazenada a menor distância em no máximo k arestas a partir da fonte
Temos dois casos (próximos slides):
d(k)[b]=min{caso 1d(k−1)[b],caso 2amin{d(k−1)[a]+w(a,b)}}
A menor distância de s a t com no máximo 1 aresta é ∞, portanto não existe um caminho até ele com 1 aresta
A menor distância de s a 2 com no máximo 2 arestas é 3 (s-v-t)
A menor distância de s a t com no máximo 1 aresta é ∞, portanto não existe um caminho até ele com 1 aresta
A menor distância de s a t com no máximo 2 arestas é 3 (s-v-t)
A menor distância de s a t com no máximo 3 arestas é 3 (s-u-v-t)
Ao final da execução, temo d(∣V∣−1)[b], que é o custo de s a v∈V(G) contendo até ∣V∣−1 arestas.
O algortimo estará correto se d(∣V∣−1)[b]=distGw(s,v)
Afirmação: Desde que não haja um ciclo negativo, d(∣V∣−1)[b]=distGw(s,v).
Dados um grafo G=(V,E) e uma função w de peso nas arestas, calcular distGw(u,v) para todo par u,v∈V(G).
Uma solução simples seria executar o algoritmo de Bellman-Ford usando cada um dos vértices como fonte
Tempo de execução O(∣V∣2∣E∣)
Podemos fazer melhor?
D(k)[u,v]=min{D(k−1)[u,v],D(k−1)[u,k]+D(k−1)[k,v]}
Algoritmo | Dijkstra | Bellman-Ford | Floyd-Warshall |
---|---|---|---|
Problema | caminho mínimo de única fonte | caminho mínimo de única fonte | caminho mínimo para todos os pares |
Complexidade | O((∥V∥+∥E∥)log∥E∥) (usando Heap) | O(∥V∥∥E∥) | O(∥V∥³) |
Vantagens | Funciona com arestas de pesos negativos, e pode detectar ciclos negativos | Funciona com arestas de pesos negativos, e pode detectar ciclos negativos | |
Desvantagens | Pode não funciona com arestas de pesos negativos | ||
Tipo | Guloso | Programação Dinâmica | Programação Dinâmica |