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