Escolar Documentos
Profissional Documentos
Cultura Documentos
Estruturas de Dados
Grafos VII:
Caminhos Mínimos (Dijkstra)
Prof. Ricardo J. G. B. Campello
Organização
Revisão de Caminhos Mínimos
Princípio da Otimalidade
Equações Funcionais (one-to-all)
Algoritmo de Dijkstra
Hipóteses
Idéia
Exemplo
Algoritmo
Justificativas
Análise de Complexidade Comparativa
1
11/13/2008 11:45 AM
Princípio de Otimalidade
Se não existirem ciclos direcionados com custo total
negativo (diciclos negativos), então:
Um sub-caminho simples de um caminho mais curto simples
é também um caminho mais curto simples por si só.
2
1 2 1 1
1 2 3
3
10 -25
1 -100 2
12
3 4 4
Presença de Diciclo Negativo: 1-2-3 é o caminho Ausência de Diciclo Negativo: 1-4-2-3 é o caminho
simples ótimo, mas 1-2 não é (ver 1-3-4-2). simples ótimo, assim como são 1-4 e 1-4-2.
Equações Funcionais i1
i2
Então: d(s) = 0
2
11/13/2008 11:45 AM
Abordagem:
gulosa (greedy)
provada ser globalmente ótima nesse caso !
3
11/13/2008 11:45 AM
Exemplo (Dijkstra)
0 0
8 A 4 8 A 4
2 2
8 7 2 1 4 8 7 2 1 3
B C D B C D
∞ 3 9 ∞ 5 3 9 8
2 5 2 5
E F E F
0 0
8 A 4 8 A 4
2 2
8 7 2 1 3 7 7 2 1 3
B C D B C D
5 3 9 11 5 3 9 8
2 5 2 5
E F E F
7
Exemplo (Dijkstra)
0
8 A 4
2
7 7 2 1 3
B C D
5 3 9 8
2 5
E F
0
8 A 4
2
7 7 2 1 3
B C D
5 3 9 8
2 5
E F
4
11/13/2008 11:45 AM
Algoritmo Dijkstra
Uma fila de prioridade Q Algoritmo Dijkstra(G, s)
armazena cada vértice v fora Q ← nova fila de prioridade
da nuvem de convergência.
para todo v ∈ vertices(G)
Vértice v armazena:
se v = s v.distance ← 0
d(v) (chave para Q).
senão v.distance ← ∞
vértice predecessor no insert(Q, v, v.distance)
caminho mínimo.
enquanto (não isEmpty(Q) )
Fila de Prioridade Q:
u ← remove(Q)
insert(Q, v, k): insere item
para todo e ∈ outgoingEdges(G, u)
v com chave k.
remove(Q): remove e z ← opposite(G, u, e)
retorna item com menor se z.distance > u.distance + e.weight
chave
z.distance ← u.distance + e.weight
replaceKey(Q, v, k):
z.parent ← u
Exercício
Execute Dijkstra no grafo direcionado abaixo a
partir da origem no vértice F:
Ilustre o conteúdo da fila de prioridade como uma
lista ordenada a cada iteração.
8 B 4
22
7 1
A C F
13 9
2 5
D E
10
5
11/13/2008 11:45 AM
Justificativa (Dijkstra)
Dijkstra é baseado na abordagem gulosa de
adicionar vértices por distância crescente:
A menor distância
d(u) fora da nuvem é 0
8 A 4
certamente definitiva 2
pois qualquer outro 8 7 2 1 3
B C D
caminho só com
5 3 9 11
pesos não negativos 2 5
E F
não pode ser menor!
11
5 0 -8 9
2 5
E F
6
11/13/2008 11:45 AM
Desempenho
Dijkstra:
É possível implementar de forma eficiente como:
O( (n + m) log n )
Comparações
Bellman-Ford (one-to-all):
Complexidade (tempo): O(nm)
Tipicamente mais lento que Dijkstra, mas menos restritivo, no
sentido que não permite apenas dicliclos negativos
É capaz de detectar naturalmente a presença de tais diciclos
Facilmente adaptável para caminhos máximos
Floyd-Warshall (all-to-all):
Complexidade (tempo): O(n3)
Tipicamente mais rápido que múltiplas execuções de Dijkstra
Também restringe apenas dicliclos negativos
Matriz de distâncias indica todas alcançabilidades entre vértices
14
7
11/13/2008 11:45 AM
Exercícios
1. Compare a complexidade computacional dos algoritmos de Dijkstra e
Bellman-Ford quando o grafo for:
esparso (m proporcional a n)
denso (m proporcional a n2)
Bibliografia
M. T. Goodrich and R. Tamassia, Data Structures and
Algorithms in C++/Java, John Wiley & Sons, 2002/2005.
16