Bellman-Ford

Context: FIT2004_MOC · single-source shortest distance when Dijkstra is illegal — negative edges allowed, and a negative cycle is reported rather than silently wrong Parent Framework: Graph

Quick Revision

  • 🎯 Objective: relax every edge, times ➔ every shortest distance is final; one extra pass that still improves something proves a negative cycle.
  • 📦 Core Components: ① init | ② distance calculation | ③ negative-cycle check — the check is not optional, it is half the algorithm.
  • ⚡ Key Constraint: buys negative edges. It is not greedy — nothing is ever finalised — so the price of dropping Dijkstra’s non-negativity precondition is a factor of .

📝 How It Works

1. Why It Is Not Greedy (LO1)

  • Dijkstra finalises, Bellman-Ford does not ➔ Dijkstra serves the closest vertex and freezes it; Bellman-Ford keeps every estimate mutable for the whole run, so a late-arriving negative edge can still lower it.
  • The cost of giving up the greedy step ➔ with no “closest vertex” to serve there is no priority queue and no ordering to exploit ⟹ every edge must be re-examined every round.
  • Dynamic Programming is what pays for it ➔ round computes the cheapest walk using at most edges, built from round ‘s answers. Optimal substructure without the greedy-choice property is exactly the greedy-vs-DP boundary.
  • Relaxation is identical to Dijkstra’s ➔ if dist[u] + w < dist[v]: dist[v] = dist[u] + w; pred[v] = u. Only the schedule of relaxations differs.

2. Why Exactly Rounds

  • A shortest path is simple ➔ if it repeated a vertex it would contain a cycle; a non-negative cycle can be deleted without getting worse, and a negative one means no shortest path exists at all.
  • Simple ⟹ at most edges ➔ “this is the maximum number of jumps without a cycle” — going you can pass through at most edges before revisiting a vertex.
  • One round extends every path by one edge ➔ after round every distance realisable in edges is correct, so round closes the longest possible simple path.
  • Round order does not matter for correctness ➔ only for how fast it converges; a lucky edge order finishes in one pass, an adversarial one needs all .

3. The Negative-Cycle Check — Repeat It ONE MORE TIME

  • Why a negative cycle kills the problem ➔ each lap round the cycle lowers the total, so the infimum is ⟹ there is no shortest distance, and returning a number would be a lie.
  • The test ➔ run the relaxation pass a -th time. If any edge still relaxes, a path of edges is beating every simple path ⟹ it must contain a cycle, and that cycle must be negative.
  • The lecture’s phrasing ➔ “if a cycle exists, this additional traversal will form the biggest cycle” — round is the first round that can only be reporting a non-simple walk.
  • Report, do not repair ➔ the unit’s pseudocode raises error "Graph contains a negative-weight cycle"; it does not return distances.
  • Only cycles REACHABLE from the source are found ➔ a vertex still at never satisfies dist[u] + w < dist[v] in a meaningful way, so an unreachable negative cycle is invisible. Detecting any negative cycle needs a weight- super source (§5) or Floyd-Warshall’s diagonal.

4. The Required Early-Termination Optimisation

  • The observation ➔ if a full pass over all edges relaxes nothing, no later pass can either — the state is a fixed point ⟹ break.
  • Implementation ➔ one boolean changed per round, set on every successful relaxation, tested at the end of the round.
  • What it buys ➔ best case collapses from to (one productive pass one confirming pass); the worst case is unmoved.
  • Free negative-cycle diagnosis ➔ if changed is still true at the end of round , the extra check pass is already implied — the two halves of the algorithm become one loop with a round counter.
  • Scope ➔ the unit outline lists this optimisation as a requirement, discussed in the studio/applied session and the bonus video; drill the exact form from that video before the competency test.

5. Any Negative Cycle, and Which Vertices Form It (applied P2, P3)

  • Super source ➔ add with a weight- edge to every vertex and run Bellman-Ford once from ⟹ every vertex is reachable, so every negative cycle is seen. , vs for one run per source.
  • The disconnected caveat ➔ the added edges make it , which collapses to only when is connected () — isolated vertices with is the case that needs the .
  • An updated vertex need not lie ON the cycle ➔ the -th pass also lowers vertices downstream of the cycle, and may leave some cycle vertices unchanged — which ones depends on the edge order. Never report the updated set as the cycle.
  • Extract by walking pred back ➔ from any vertex updated in the -th pass, follow pred until a vertex repeats; the cycle is plus every vertex between its two occurrences. A visited array costs auxiliary.
  • -auxiliary variant ➔ step back times first — guaranteed to land on the cycle — then follow pred once round until returning to that vertex.
  • Cost ➔ run walk ⟹ .

⚙️ Core Implementation

🔹 Bellman-Ford (unit pseudocode early exit)

🔹 Extract one negative cycle (applied P3)

⚖️ Complexity

Adjacency list (an edge list is enough — Bellman-Ford never asks for a vertex’s neighbours).

CaseTimeAuxiliary spaceTrigger
Best (with early exit)one pass fixes everything, the second confirms it
Best (textbook, no early exit)the loop is input-independent — best worst
Average / Worst rounds relaxations, for the check
Dense instantiation
  • Derivation ➔ init outer loop inner loop check .
  • Auxiliary is , not ➔ only dist and pred are stored; the rounds overwrite one array in place. The trace table’s grid is a revision device, not the implementation.
  • All-pairs by repetition ➔ dense ⟹ strictly worse than Floyd-Warshall’s .

⚖️ Core Decision Matrix

SituationReach forWhyCost
All , single sourceDijkstragreedy finalisation is sound
Some , single sourceBellman-Fordnothing is finalised, so a late improvement still lands
Need to know whether a negative cycle existsBellman-Ford step 3the -th pass is the certificate extra
Negative cycle anywhere in Bellman-Ford from a weight- super source (§5)one run reaches every vertex
… and the all-pair matrix is wanted tooFloyd-Warshalla negative diagonal entry
All pairs, negatives, denseFloyd-Warshall beats
All pairs, negatives, sparseJohnson’sone Bellman-Ford reweights every edge to , then Dijkstras
Weights and all pairs and sparse Dijkstra beats when

When It Flips: the hinge is the sign of the weights, then the number of sources, then density. One negative edge moves you from Dijkstra to Bellman-Ford; needing all pairs moves you to Floyd-Warshall on a dense graph and to Johnson's — one Bellman-Ford, then Dijkstras — on a sparse one. separate Bellman-Fords is never the answer.

📊 Exam Execution Trace & Applied Exercises

Lecture graph — , , , , , . Source . Cells read value predecessor.

Manual Execution Trace

VertexChecking pass
⟹ break
⟹ break too

Final Extracted Output: the checking pass still improves and ⟹ negative cycle, so the algorithm returns an error, not the column. The culprit is at , and every lap round it drives and down by a further .

  • Read the trap ➔ the column looks like a finished answer. Without step 3 you would hand it in. A Bellman-Ford answer is only an answer once the extra pass changes nothing.
  • Read the DP layering ➔ is until because the shortest walk needs three edges; a vertex first becomes finite in round its hop count from .

Applied Exercise — bound the damage of a single negative edge

Problem: show a graph where Dijkstra is wrong but Bellman-Ford is right, using only the graph above’s shape.

Final Extracted Output: via . The recipe: a cheap-looking direct edge that is beaten by a longer route ending in a negative edge — exactly the greedy-finalisation failure, with no cycle needed.

Applied Exercise — the updated vertex is off the cycle (applied P3)

Problem: , , , ( already plays the super source), , , , . Output the vertices of a negative cycle.

Final Extracted Output: the cycle is . Read the trap ➔ the updated set contains , which is off the cycle (it only hangs off ), and misses and , which are on it.

⚠️ Common Mistakes

  • 💡 Looping times “to be safe” ➔ the -th pass is the cycle check; folding it into the main loop destroys the diagnosis and silently returns -bound garbage.
  • 💡 “Bellman-Ford handles negative cycles” ➔ it detects them. No algorithm can return a shortest distance that does not exist.
  • 💡 Claiming it finds every negative cycle ➔ only those reachable from the source. Say so, and offer the weight- super source or Floyd-Warshall as the fix.
  • 💡 Reporting the vertices updated in the -th pass as the cycle ➔ downstream vertices update too and some cycle vertices may not; walk pred back to a repeat (§5).
  • 💡 Quoting or ➔ the bound is ; the dense instantiation is , and it must be stated with named (Graph §3).
  • 💡 Storing a table ➔ auxiliary space is ; the grid exists only for hand-tracing.

🧠 Active Recall