O algoritmo de Dijkstra, criado por Edsger Dijkstra em 1956, calcula o menor caminho entre um nó e todos os outros em um grafo com pesos. O simulador mostra em cada passo qual nó foi escolhido, quais arestas foram relaxadas e como a tabela de distâncias muda, exatamente como em um exercício resolvido de estrutura de dados.
Passo a Passo do Algoritmo
- Defina distância 0 para a origem e ∞ para todos os outros nós.
- Escolha o nó não visitado com a menor distância e marque-o como visitado.
- Para cada vizinho não visitado, calcule distância do nó atual + peso da aresta.
- Se esse valor for menor que a distância atual do vizinho, atualize e guarde o nó atual como “anterior”.
- Repita até visitar todos os nós alcançáveis.
- Para reconstruir o caminho, siga os “anteriores” do destino até a origem.
Dijkstra em Python (com heap)
import heapq
def dijkstra(grafo, origem):
dist = {n: float("inf") for n in grafo}
dist[origem] = 0
fila = [(0, origem)]
while fila:
d, u = heapq.heappop(fila)
if d > dist[u]:
continue
for v, peso in grafo[u]:
if d + peso < dist[v]:
dist[v] = d + peso
heapq.heappush(fila, (dist[v], v))
return dist
grafo = {"A": [("B", 4), ("C", 2)], "B": [("D", 10)], "C": [("E", 3)],
"D": [], "E": [("D", 4)]}
print(dijkstra(grafo, "A"))Dijkstra em C (versão O(V²))
#define V 6
#define INF 1000000
void dijkstra(int g[V][V], int origem, int dist[V]) {
int visitado[V] = {0};
for (int i = 0; i < V; i++) dist[i] = INF;
dist[origem] = 0;
for (int k = 0; k < V; k++) {
int u = -1;
for (int i = 0; i < V; i++)
if (!visitado[i] && (u == -1 || dist[i] < dist[u])) u = i;
if (dist[u] == INF) break;
visitado[u] = 1;
for (int v = 0; v < V; v++)
if (g[u][v] && dist[u] + g[u][v] < dist[v])
dist[v] = dist[u] + g[u][v];
}
}Dijkstra em Java
int[] dijkstra(List<List<int[]>> adj, int origem) {
int[] dist = new int[adj.size()];
Arrays.fill(dist, Integer.MAX_VALUE);
dist[origem] = 0;
PriorityQueue<int[]> fila = new PriorityQueue<>(Comparator.comparingInt(a -> a[1]));
fila.add(new int[]{origem, 0});
while (!fila.isEmpty()) {
int[] atual = fila.poll();
int u = atual[0];
if (atual[1] > dist[u]) continue;
for (int[] aresta : adj.get(u)) {
int v = aresta[0], peso = aresta[1];
if (dist[u] + peso < dist[v]) {
dist[v] = dist[u] + peso;
fila.add(new int[]{v, dist[v]});
}
}
}
return dist;
}Perguntas Frequentes
Para que serve o algoritmo de Dijkstra?
Para encontrar o caminho de menor custo de um nó de origem até todos os outros nós de um grafo com pesos não negativos. É a base de aplicativos de rota (GPS), roteamento de redes (protocolo OSPF) e jogos.
Como o algoritmo de Dijkstra funciona?
Começa com distância 0 na origem e infinito nos demais. A cada passo, escolhe o nó não visitado com menor distância, marca como visitado e tenta melhorar (relaxar) a distância de cada vizinho passando por ele. Repete até visitar todos.
Por que Dijkstra não funciona com pesos negativos?
Porque ele assume que, ao visitar um nó, sua distância é definitiva. Com uma aresta negativa, um caminho descoberto depois poderia diminuir essa distância. Para pesos negativos, use o algoritmo de Bellman-Ford.
Qual a complexidade do algoritmo de Dijkstra?
Com uma fila de prioridade (heap binário), O((V + E) log V), em que V é o número de vértices e E o de arestas. Na versão simples, que procura o mínimo varrendo todos os nós, é O(V²).
