Slide 1 - claudiaboeres

Propaganda
Algoritmos de Caminho Mínimo
em Grafos
CC/EC/Mestrado
Teoria dos Grafos
CC/EC/PPGI/UFES
CAMINHOS MAIS CURTOS
CC/EC/PPGI/UFES
Caminhos mais Curtos
•
Dados: grafo G=(V,A) orientado e
distância cij associada ao arco (i,j)  A.
Problema: Obter o caminho mais curto entre dois nós s e t.
O comprimento de um caminho é igual à soma dos
comprimentos (distâncias) dos arcos que formam o caminho.
A “distância” ou “comprimento” de um arco pode ter diversas
interpretações dependendo da aplicação: custos, distâncias, consumo
de combustível, etc.
Exemplo 1: Dado um mapa rodoviário, determinar a rota mais
curta de uma cidade a outra.
(rota mais rápida,
rota com menor consumo de combustível, ...)
CC/EC/PPGI/UFES
Caminhos mais Curtos
Exemplo 2: Construção de uma estrada entre duas cidades A e
K. O grafo abaixo representa os diversos trechos possíveis e o
custo de construção de cada um. Determinar o trajeto ótimo
cujo custo de construção seja mínimo (corresponde a achar o
caminho mais curto de A a K em relação a estes custos).
B
2
8
5
C
D
Solução:
4
4
F
I
2
4
4
7
H
4
4
5
A
E
6
5
K
2
4
2
G
4
J
A–D–G–I–K
custo = 7 + 2 + 2 + 5 = 16
CC/EC/PPGI/UFES
Caminhos mais Curtos
•
Condição de existência:
Caminho de i a j contendo um ciclo w:
k
j
i
w
Comprimento do caminho =
comprimento (i  k) +
comprimento (w) +
comprimento (k  j)
Qual é o comprimento do caminho mais curto de i a j se o
comprimento do ciclo w é negativo?
CC/EC/PPGI/UFES
Caminhos mais Curtos
Condição de existência:
não há ciclos de comprimento negativo.
A solução ótima (caminho mais curto) sempre será um
caminho elementar (sem ciclos).
CC/EC/PPGI/UFES
Caminhos mais Curtos
Caminho mais curto:
- De um nó a outro
- De um nó a todos os demais
- Entre todos os pares de nós de um grafo
CC/EC/PPGI/UFES
Caminhos mais Curtos
Caminho mais curto do nó 1 a cada nó do grafo G=(V,A)
Hipótese: todas as distâncias cij são positivas:
cij ≥ 0, (i,j)  A
Algoritmo de Moore-Dijkstra (1957-1959)
*(i) = comprimento do caminho mais curto do nó 1 ao nó i
Em especial, *(1)=0 (distâncias positivas).
Algoritmo com n-1 iterações
No início de cada iteração, o conjunto V de nós está particionado
em dois subconjuntos S e S, com o nó 1 em S.
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
1. o grafo inicial
8. fim-enquanto
CC/EC/Mestrado
CC/EC/PPGI/UFES
Ciclos negativos....
{j,i}
1
3
2
10
1
d(1, i)
0
anterior(i)
0
2
3


0
0
-13
3
3
2
-29
10
-5
-21
10
1
2
111
2
Teoria dos Grafos
-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
•
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
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