Documente Academic
Documente Profesional
Documente Cultură
Algoritmo de Dijkstra
Hipteses Idia Exemplo Algoritmo Justificativas
Grafos Ponderados
Um grafo ponderado um grafo que possui rtulos numricos (pesos) associados a cada aresta. Possui ampla aplicabilidade. Existem algoritmos especializados para calcular o caminho mais curto (shortest path) entre quaisquer dois vrtices do grafo. Por exemplo:
Bellman-Ford, Floyd-Warshall, Dijkstra, entre outros.
Grafos Ponderados
Estrutura de Dados Simples:
SFO
ORD LGA
PVD
HNL
LAX
DFW
MIA
Propriedades
Propriedade 1
(a) Qualquer grafo no direcionado ou misto pode ser transformado em direcionado (digrafo puro) substituindo cada aresta no direcionada por duas em direes opostas; e (b) Grafos no ponderados podem ser considerados ponderados com pesos unitrios.
1
Exemplo:
Caminho mais curto entre Providence (PVD) e Honolulu (HNL)
1 4
1 1
1 1
4
1 1
2 5
2 5
1
Propriedades
Propriedade 2 (Princpio de Otimalidade)
Se no existirem ciclos direcionados com custo total negativo (diciclos negativos), ento:
Um sub-caminho simples de um caminho mais curto simples tambm um caminho mais curto simples por si s. Em outras palavras, se um vrtice x faz parte do caminho mais curto de um outro vrtice u at um terceiro vrtice v, ento o sub-caminho entre u e x o caminho mais curto entre esses dois vrtices.
1 2 2 1 1 2 1 3
Propriedades
Propriedade 3
A propriedade 2 implica que existe uma rvore de caminhos mais curtos simples de um vrtice inicial at todos os outros vrtices. Exemplo (a partir de PVD):
PVD
10
-25
LAX
1 4 -100 2
DFW MIA
12
Presena de Diciclo Negativo: 1-2-3 o caminho simples timo, mas 1-2 no (ver 1-3-4-2).
Ausncia de Diciclo Negativo: 1-4-2-3 caminho simples timo, assim como so 1-4, 1-4-2, 4-2, 4-2-3 e 2-3.
Abordagem:
gulosa (greedy) provada ser globalmente tima nesse caso!
Apenas os vrtices adjacentes a u que ainda no convergiram precisam ser atualizados, o que torna Dijkstra muito eficiente.
9
Exemplo (Dijkstra)
0 8 2 B 2 8 E 7 3 C 2 9 F 1 5 2 D 4 B 8 7 5 E 3 A 4 8 2 C 2 9 F 1 8 D 5 3 A 0 4
Exemplo (Dijkstra)
0 8 2 B 2 7 5 E 7 3 C 2 9 F 1 8 D 5 0 8 4 2 9 F 1 8 3 B 2 5
11
4 3
0 8 2 B 2 8 7 5 E 3 C 2 9 F 1 11 D 5 3 B 2 7 7 5 E 3 A 4 8 2 C A
A 2 7 5 E 3 2 9 F 1 8
4 3
D 5
12
Algoritmo Dijkstra
Uma fila de prioridade Q armazena cada vrtice v fora da nuvem de convergncia. Vrtice v armazena:
d(v) (chave para Q)
varivel v.distance
Exerccio
Execute Dijkstra no grafo direcionado abaixo a partir da origem no vrtice F:
Ilustre o contedo da fila de prioridade como uma lista ordenada a cada iterao.
B 22 A 2 7 13 D C 9 E 5
14
Fila de Prioridade Q:
insert(Q, v, k): insere item v com chave k remove(Q): remove e retorna item com menor chave replaceKey(Q, v, k): substitui por k a chave do item v e reorganiza a fila
Algoritmo Dijkstra(G, s) Q nova fila de prioridade para todo v vertices(G) se v = s v.distance 0 seno v.distance insert(Q, v, v.distance) enquanto empty(Q) u remove(Q) para todo e outgoingEdges(G, u) z opposite(G, u, e) se z.distance > u.distance + e.weight z.distance u.distance + e.weight z.parent u replaceKey(Q, z, z.distance)
* Nota: varivel e.weight o peso armazenado na aresta e
Justificativa (Dijkstra)
Dijkstra baseado na abordagem gulosa de adicionar vrtices por distncia crescente:
A menor distncia d(u) fora da nuvem certamente definitiva pois qualquer outro caminho s com pesos no negativos no pode ser menor!
0 8 2 B 2 8 7 5 E 3 C 2 9 F 1 11 D 5 3 A 4
0 8 6 7 5 E 7 0 C 5 -8 F 1 9 D 5 4 A 4
Desempenho
Dijkstra:
possvel implementar de forma eficiente como:
O( (n + m) log n )
Comparaes
Bellman-Ford (one-to-all):
Complexidade (tempo): O(nm) Tipicamente mais lento que Dijkstra, mas menos restritivo, no sentido que restringe apenas dicliclos negativos capaz de detectar naturalmente a presena de tais diciclos Facilmente adaptvel para caminhos mximos
Alternativamente, pode-se substituir a fila de prioridade por uma busca seqencial em uma lista: O ( n2 + m)
Pode ser mais rpida para grafos densos (m grande). Implementao em C: ver (Skiena & Revilla, 2003).
Floyd-Warshall (all-to-all):
Complexidade (tempo): O(n3) Tipicamente mais rpido que mltiplas execues de Dijkstra Tambm restringe apenas dicliclos negativos
17
Exerccios
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)
Referncias
M. T. Goodrich and R. Tamassia, Data Structures and Algorithms in C++/Java, John Wiley & Sons, 2002/2005. N. Ziviani, Projeto de Algoritmos, Thomson, 2a. Edio, 2004. T. H. Cormen, C. E. Leiserson, and R. L. Rivest, Introduction to Algorithms, MIT Press, 2nd Edition, 2001. S. Skiena e M. Revilla, Programming Challenges: The Programming Contest Training Manual, Springer-Verlag, 2003.
2.
Desenhe um grafo no-direcionado simples, conexo e ponderado com 8 vrtices e 16 arestas. Transforme esse grafo em um digrafo e exercite o algoritmo Dijkstra executando-o manualmente a partir de diferentes origens:
Apresente cada execuo atravs de duas matrizes, uma com as distncias (d[k]) e outra com os vrtices predecessores nos caminhos mnimos (p[k]). Nessas matrizes, cada coluna k corresponde a um vrtice do grafo e cada linha t corresponde a uma iterao do algoritmo Apresente tambm a rvore de caminhos mnimos resultante de cada execuo
3.
Retire algumas arestas do grafo do exerccio anterior de forma tal que o digrafo permanea fortemente conexo e cada par de vrtices adjacentes s possua uma aresta direcionada incidente em ambos. Ento repita o Exerccio 2.
20