Algoritmo de Caminho Mínimo
CC/EC/Mestrado
Teoria dos Grafos
CC/EC/PPGI/UFES
Algoritmo de Dijkstra
•
Resolve o problema com um vértice-fonte
em grafos cujas arestas tenham peso
maior ou igual a zero. Este algoritmo é
capaz de determinar o caminho mínimo, a
partir de um vértice inicial v, para todos os
outros vértices do grafo.
CC/EC/Mestrado
Teoria dos Grafos
CC/EC/PPGI/UFES
Algoritmo de Dijkstra
vINI = vértice inicial
d(vINI, vINI) = 0
d(vINI, i) = INFINITO, i, i  V – {vINI}
fechado = 
aberto = V
anterior(i) = 0, i, i  V
enquanto(aberto ≠ ) {
k = vértice pertencente a aberto, mais próximo do vértice inicial
fechado = fechado  k; aberto = aberto – k;
para cada vizinho i de k que está em aberto faça{
custo = min{d(vINI, i), d(vINI,k) + c(k,i)}
se (custo < d(vINI, i)) então
d(vINI, i) = custo; anterior(i) = k
}
}
CC/EC/Mestrado
Teoria dos Grafos
CC/EC/PPGI/UFES
Execução
7. 2 é o vértice 13.
de menor
6 é o custo;
vértice de menor custo;
fechado = fechado+{6}
fechado = fechado+{2}
2. inicializando os custos
8. examinando os vértices vizinhos ao
14. fim alcançado
2
3. atualizando o conjunto
fechado
9. 4 é o vértice de menor custo;
4. examinando os vértices
ao
fechado vizinhos
= fechado+{4}
1 que estão em aberto
10. examinando os vértices vizinhos
5. 3 é o vértice de
custo;
ao menor
4
fechado = fechado+{3}
11. 5 é o vértice de menor custo;
6. examinando os fechado
vértices= vizinhos
ao
fechado+{5}
3
12. examinando os vértices vizinhos
ao 5
1. o grafo inicial
fim do algoritmo
CC/EC/Mestrado
Teoria dos Grafos
CC/EC/PPGI/UFES
Outros algoritmos de
caminho mínimo
• Algoritmo de Bellmann-Ford
• Algoritmo de Floyd
CC/EC/Mestrado
Teoria dos Grafos
CC/EC/PPGI/UFES
Algoritmo de Bellmann-Ford
Entrada: matriz de pesos das arestas c(i, j) de G = (V,E)
1. v_inicial ← vértice inicial;
2. d(v_inicial, v_inicial)←0;
3. d(v_inicial, i)←INFINITO,para todo
i de V – v_inicial
4. anterior(i)←0, para todo i de V
5. enquanto  (j, i) de E tal que d(v_inicial, i) > d(v_inicial, j) + c(j, i) faça
6.
d(v_inicial, i) ← d(v_inicial, j) + c(j, i)
7.
anterior(i) ← j
{j,i}
1
3
8. fim-enquanto
1
2
3
d(1, i)
0
3
3
2
-29
-13
10
-5
-21
10

anterior(i)
0
012
01112
CC/EC/Mestrado
Teoria dos Grafos
2
10
-8
3
{1,2}
(1,2)
{1,3}
(2,1)
{2,3}
(1,3)
(3,1)
(2,3)
(3,2)
CC/EC/PPGI/UFES
Caminhos mais Curtos
Caminho mais curto entre todos os pares de nós de um grafo
•
Dados:
Grafo G=(V, A), |V | = n.
Não há circuitos negativos.
c = {cij}, j = 1,...,n, i = 1,...,n
cij ≥ 0
cii = 0
cij = +, (i, j )  A
Ak(i, j ) = valor do caminho mais curto de i a j podendo
usar apenas nós numerados de 1 a k como nós
intermediários.
CC/EC/PPGI/UFES
Caminhos mais Curtos
A0(i, j ) = cij : caminho mais curto de i a j usando no máximo o nó
“0” (que não existe) como nó intermediário
(caminho mais curto de i a j sem nós
intermediários)
Ak(i, j ) : pode usar o nó k ou não.
Ak+1(i, j ) : pode usar o nó k+1 ou não.
A0  A1
A1  A2
...
An-1  An
An(i, j ) = valor do caminho mais curto
de i a j podendo usar
qualquer nó de 1 a n como
nó intermediário.
CC/EC/PPGI/UFES
Caminhos mais Curtos
•
Se Ak+1(i, j ) não usa o nó k+1 como intermediário, então:
Ak+1(i, j ) = Ak(i, j )
Se Ak+1(i, j ) usa o nó k+1 como intermediário, então:
Ak+1(i, j ) = Ak(i, k+1) + Ak(k+1, j )
Ak+1(i, j ) = min { Ak(i, j ), Ak(i, k+1) + Ak(k+1, j ) }
CC/EC/PPGI/UFES
Caminhos mais Curtos
Algoritmo de Floyd:
Para i = 1,...,n faça
Para j = 1,...,n faça
A0(i,j)  cij
fim-para
fim-para
Para k = 1,...,n faça
Para i = 1,...,n faça
Para j = 1,...,n faça
Ak(i,j)  min{Ak-1(i,j),
Ak-1(i,k) + Ak-1(k,j)}
fim-para
fim-para
fim-para
CC/EC/PPGI/UFES
Caminhos mais Curtos
Exemplo:
6
1
2
4
3
C=
11
2
0
4
11
6
0
2
3
+∞
0
A0 =
0
4
11
6
0
2
3
+∞
0
0
4
6
5
0
2
3
7
0
3
A1 =
0
4
11
6
0
2
3
7
0
A2 =
0
4
6
6
0
2
3
7
0
A3 =
CC/EC/PPGI/UFES
Caminhos mais Curtos
Algoritmo de Dijkstra: número de operações (tempo) ~ n2
n-1 iterações, cada iteração busca o mínimo em uma lista com
até n-1 elementos
Algoritmo de Floyd: número de operações (tempo) ~ n3
Três comandos for de 1 até n um dentro do outro
Ou seja, o problema de calcular os caminhos mais curtos entre
todos os pares de nós pode ser resolvido com a mesma
eficiência aplicando-se n vezes o algoritmo de Dijkstra, uma vez
a partir de cada nó inicial.
CC/EC/PPGI/UFES
Floyd em grafos não
direcionados?
Como aplicar o algoritmo de Floyd no grafo abaixo?
1
3
2
10
-8
3
CC/EC/PPGI/UFES
Download

A 0 - claudiaboeres