Bellman-Ford Algorithm
Overview
Bellman-Ford solves the SSSP problem for graphs that may contain negative edge weights. The only restriction is that there be no negative-weight cycle reachable from the source (if one exists, shortest paths are undefined). The algorithm also explicitly detects negative cycles and reports failure.
Unlike Dijkstra, which selects vertices greedily, Bellman-Ford relaxes every edge times. This brute-force approach ensures distances propagate correctly along all possible simple paths.
Pseudocode
BELLMAN-FORD(G, w, s):
for each v in G.V:
v.d = ∞
v.π = NIL
s.d = 0
for i = 1 to |G.V| - 1:
for each edge (u, v) in G.E: // in any order
RELAX(u, v, w)
// Negative cycle detection pass
for each edge (u, v) in G.E:
if v.d > u.d + w(u, v):
return FALSE // negative cycle exists
return TRUE
Why Iterations Suffice
A simple shortest path has at most edges (no vertex is repeated). Consider a shortest path with .
- After iteration 1: edge is relaxed, so . (In fact if no shorter alternative exists.)
- After iteration 2: edge is relaxed, so .
- …
- After iteration : .
Since , after iterations all vertices have . This can be formalised as dynamic programming: let be the shortest path weight using at most edges. The recurrence is exactly what the relaxation loop computes bottom-up.
Negative Cycle Detection
After passes over all edges, every should equal (or for unreachable vertices). If any edge can still be relaxed (i.e. for some ), then:
- There exists a path of length whose weight decreases from the current values.
- Such a path must contain at least edges, so it contains a cycle (by the pigeonhole principle).
- Removing that cycle cannot increase path weight (or the path wouldn’t be shorter), so the cycle must have negative total weight.
Thus a relaxable edge after passes indicates a negative-weight cycle reachable from .
Important caveat: A negative cycle that is not reachable from will not be detected, because vertices in that component maintain throughout and no edge from a finite-distance vertex enters the component. This does not affect the SSSP result for reachable vertices.
Worked Example (No Negative Cycle)
Same graph as Dijkstra notes: , source . Weights: , , , , , , .
Processing edges in the order: (E,A), (E,F), (E,G), (A,B), (A,C), (G,F), (C,D).
| Vertex | Init | |||
|---|---|---|---|---|
| E | 0 | 0 | 0 | 0 |
| A | 5 (E) | 5 | 5 | |
| B | 6 (A) | 6 | ||
| C | 7 (A) | 7 | ||
| D | 9 (C) | |||
| F | 7 (E) | 6 (G) | 6 | |
| G | 3 (E) | 3 | 3 |
After , all distances are final. Iterations 3-6 make no changes. Final check: no edge can be relaxed return TRUE.
Worked Example (Negative Cycle)
Modify the graph: change from 3 to , add edge with weight , add edge with weight . The cycle has weight (negative).
Run Bellman-Ford. After , is set to 7 (via A). After , is set to 5 (via C), and is set to (via D). After , drops further, and so on. The values keep decreasing each iteration because the negative cycle propagates smaller distances indefinitely. After the full passes, the final check finds that some edge (e.g. ) can still be relaxed. The algorithm returns FALSE.
Early Termination and Practical Optimisations
- If a complete pass over all edges produces no changes, all distances are final. The algorithm can terminate early. This does not improve the worst case but helps on well-behaved inputs.
- Process edges in an order that respects topological order if the graph is a DAG (then only one pass is needed: DAG-SSSP in ).
- Use a queue of vertices whose value changed in the previous pass (Shortest Path Faster Algorithm, SPFA), which often runs faster in practice though its worst case remains .
Running Time
- Initialisation: .
- Main loop: iterations, each scanning all edges: .
- Final detection pass: .
- Total: .
For dense graphs: . For sparse graphs: if .
Comparison
| Property | Dijkstra | Bellman-Ford |
|---|---|---|
| Edge weights | Non-negative only | Any real |
| Negative cycle detection | No | Yes |
| Time complexity | ||
| Algorithm type | Greedy | Dynamic programming (implicit) |
| Practical use | Faster for | Necessary for negative edges |
Summary
| Property | Detail |
|---|---|
| Weight constraint | Any real numbers |
| Negative cycles | Detected on final extra pass |
| Why passes | Simple shortest path has edges |
| Time | |
| Space | beyond graph storage |
| Convergence check | No changes in a pass done |
Past paper questions: y2026p1q9(c,d) (undetected negative cycles, purpose of extra relaxation pass, early termination optimisation).