Dijkstra's Algorithm: Shortest Path Visualization

simulator intermediate ~10 min
Loading simulation...
Dijkstra's algorithm finds the globally optimal shortest path using greedy expansion.

Dijkstra's algorithm guarantees the shortest path in graphs with non-negative edge weights by always expanding the nearest unvisited node. Time complexity is O((V + E) log V) with a binary heap.

Formula

d(v) = min(d(v), d(u) + w(u, v)) β€” edge relaxation
T(V, E) = O((V + E) log V) β€” binary heap implementation

The Algorithm That Powers Every GPS

Edsger Dijkstra conceived his shortest-path algorithm in 1956 while sitting at a cafΓ© in Amsterdam, working it out in about twenty minutes on paper. Published in 1959, it became one of the most widely used algorithms in computer science β€” the backbone of GPS navigation, network routing protocols like OSPF, and countless logistics systems. Its elegance lies in a simple greedy principle: always expand the closest unvisited node.

How Dijkstra's Algorithm Works

The algorithm maintains a set of visited nodes and a priority queue of tentative distances. Starting from the source node with distance zero, it repeatedly extracts the nearest unvisited node, marks it as permanent, and updates the distances of its neighbours. This 'relaxation' step ensures that when a node is dequeued, its recorded distance is optimal. The process continues until the target is reached or all reachable nodes are visited.

Correctness and Limitations

Dijkstra's correctness depends on one critical assumption: all edge weights must be non-negative. If a negative-weight edge exists, a node that was already finalized might later be reachable via a shorter path, violating the greedy invariant. For graphs with negative weights, Bellman-Ford provides a correct alternative at higher computational cost. For unweighted graphs, a simple BFS suffices.

From Theory to Practice

Modern routing engines like those in Google Maps don't run vanilla Dijkstra on the entire road network. They use hierarchical preprocessing techniques β€” contraction hierarchies, hub labelling, and A* with landmark heuristics β€” that answer continental-scale queries in microseconds. Yet every one of these advanced methods builds on Dijkstra's foundational insight: expand outward from the source in order of increasing distance.

FAQ

How does Dijkstra's algorithm find the shortest path?

Dijkstra's algorithm maintains a priority queue of tentative distances from the source. At each step it extracts the node with the smallest tentative distance, marks it as visited, and relaxes all its outgoing edges. Because it always processes the nearest unvisited node, it guarantees optimality for non-negative weights.

What is the time complexity of Dijkstra's algorithm?

With a binary heap priority queue the time complexity is O((V + E) log V), where V is the number of vertices and E is the number of edges. Using a Fibonacci heap reduces this to O(E + V log V), though the constant factors are larger.

Can Dijkstra's algorithm handle negative edge weights?

No. Dijkstra's algorithm assumes non-negative edge weights. With negative weights the greedy choice can be wrong. For graphs with negative edges (but no negative cycles) use the Bellman-Ford algorithm.

What is the difference between Dijkstra and A* search?

A* extends Dijkstra by adding a heuristic estimate of the remaining distance to the goal. This guides the search toward the target and can dramatically reduce the number of nodes explored while still guaranteeing optimality if the heuristic is admissible.

Sources

Embed

<iframe src="https://homo-deus.com/lab/graph-theory/shortest-path/embed" width="100%" height="400" frameborder="0"></iframe>
View source on GitHub