Floyd-Warshall

Context: FIT2004_MOC · all-pair shortest distance on an adjacency matrix, negative edges allowed — three nested loops that beat running Dijkstra or Bellman-Ford from every vertex Parent Framework: Graph

Quick Revision

  • 🎯 Objective: for every intermediate vertex in turn, ask “is cheaper than ?” ➔ after all values of , every entry is the true shortest distance.
  • 📦 Core Components: Warshall’s (boolean, or/and) ➔ transitive closure | Floyd-Warshall (numeric, min/+) ➔ distances | the diagonal ➔ negative-cycle certificate.
  • ⚡ Key Constraint: time and space unconditionally — it never looks at , so it is the wrong tool on a sparse graph and the right one on a dense one.

📝 How It Works

1. Warshall’s Algorithm — Transitive Closure (reachability)

  • The object ➔ given , the transitive closure is : the same vertices, plus an edge whenever a path exists in .
  • The rule is transitivity ➔ and therefore ; on the boolean adjacency matrix that reads .
  • One line of code ➔ m[i][j] = m[i][j] or (m[i][k] and m[k][j]) inside for k / for i / for j.
  • Answers the reachability question in afterwards ➔ the closure is a lookup table; building it once beats separate traversals only when the graph is dense ( vs ).
  • Cost ➔ time , space for the matrix.

2. Floyd-Warshall — the Same Loop, With Distances

  • The upgrade ➔ replace the boolean semiring with the arithmetic one : m[i][j] = min(m[i][j], m[i][k] + m[k][j]).
  • The transitivity becomes an inequality ➔ is a cost of ; taking the over every intermediate makes it the shortest.
  • Doing it for every gives all pairs ➔ the matrix is the output, so there is no source vertex and no per-source rerun.
  • Initialisation, in three moves ➔ ① diagonal (itself back to itself costs nothing) ② every edge written as ③ for every non-edge.
  • Negative edges are fine ➔ nothing is finalised and nothing is compared for “closest”, so Dijkstra’s precondition never applies.

3. Why Must Be the OUTER Loop (the DP layering — LO1)

  • The subproblem ➔ after the -th outer iteration, is the shortest walk whose intermediate vertices all come from . The endpoints are unrestricted.
  • The recurrence ➔ — either the new intermediate helps, or it does not.
  • The lecture’s phrasing ➔ “as we increment, we find the minimum distance going through vertex ; thus we would have the minimum through every vertex, updating as needed.”
  • This is Dynamic Programming ➔ optimal substructure over a growing set of permitted intermediates, subproblems at each ⟹ falls straight out of the MEMO-sizing rule.
  • In-place is safe ➔ row and column cannot change during iteration (using as its own intermediate adds ), so one matrix suffices instead of of them.

4. Negative-Cycle Detection — Read the Diagonal

  • The test ➔ after the run, any means a negative cycle exists. The diagonal is “vertex back to vertex ”, so a negative entry is literally a negative closed walk.
  • Stronger than Bellman-Ford’s ➔ Bellman-Ford only sees cycles reachable from its source; Floyd-Warshall considers every vertex as a start, so it finds any negative cycle in the graph.
  • What to report ➔ distances through a negative cycle are , not numbers; state that no shortest distance exists for those pairs rather than handing over the matrix.
  • The post-process (applied P5) ➔ for every with , set for every pair with and — reaches the cycle and the cycle reaches ⟹ one more triple loop, , bound unchanged.
  • Contamination is wider than the diagonal ➔ one flagged can send most of the matrix to , so a single negative diagonal entry invalidates far more than one cell.

5. Reading the Path Out, Not Just the Distance (applied P4)

  • Distances alone are not paths ➔ keep a second matrix, written only when the min takes the branch ⟹ still time and space.
  • succ — the sheet’s preferred form ➔ the first vertex after on a shortest . Init for every edge; on an update (the first step towards is now the first step towards ). Rebuild by u = succ[u][v] until ⟹ with plain appends.
  • mid — divide and conquer ➔ on an update ; rebuild as path path, dropping the duplicated middle vertex. only if concatenation is ⟹ linked lists.
  • pred — the mirror of succ ➔ , walked backwards from and reversed — the same move as Dijkstra’s v.previous, one dimension wider.

⚙️ Core Implementation

🔹 Warshall’s transitive closure

🔹 Floyd-Warshall all-pair shortest distance

🔹 Path rebuild from succ (applied P4)

🔹 post-process (applied P5 — in place of the error, when the matrix is wanted)

⚖️ Complexity

Adjacency matrix (mandatory — the algorithm indexes in ).

CaseTimeAuxiliary spaceTrigger
Best Average Worstthree fixed nested loops — no input-dependent branching, so there is no bad case, only a big
Warshall’s closureidentical loop, boolean payload
With path reconstructiona second matrix is the same order
With post-processone more triple loop, only for flagged
  • Derivation ➔ iterations work ; init is and the diagonal check , both dominated.
  • The matrix is INPUT, the answer is OUTPUT ➔ if the graph arrives as a matrix, the is input space; a list-to-matrix conversion makes it auxiliary (Algorithmic Complexity §6). Say which you are counting.
  • never appears ➔ a sparse graph costs exactly as much as a complete one, which is the whole selection rule below.

⚖️ Core Decision Matrix

RequirementReach forCostNegative edges?
Reachability, all pairs, denseWarshall’s closuren/a
Reachability, all pairs, sparseDFS from every vertexn/a
APSP, dense graphFloyd-Warshall✅ (no negative cycle)
APSP, sparse, all Dijkstra dense❌
APSP, sparse, some Johnson’s (applied)✅ (no negative cycle)
Single source onlyDijkstra / Bellman-Ford / —
Any negative cycle anywhereFloyd-Warshall diagonalthat is the point

When It Flips: the hinge is density, not weight sign. Dijkstras cost — directly when , after Johnson's reweighting when some — and beat exactly while , i.e. on a sparse graph. Once , the lecture's comparison makes Floyd-Warshall the outright winner.

📊 Exam Execution Trace & Applied Exercises

Lecture graph — , , , , . Vertex order .

Initial matrix (diagonal · edges written in · elsewhere)

Manual Execution Trace

Only cells that actually change are listed; every other cell survives the round unchanged.

(new intermediate)CellOldNewArithmetic

Final Extracted Output

  • Diagonal all ⟹ no negative cycle; independently, the only cycle weighs .
  • Every entry is finite ⟹ the transitive closure of this digraph is the complete graph on — Warshall’s on the same input returns all-True.
  • Read the trap ➔ uses the already-updated , not the original . In-place updating is correct here (§3), but you must carry the current matrix forward, not the initial one.
  • Read the layering ➔ the round in which a cell first becomes finite is the round that admits the last intermediate its route needs; waits for because its route is .

Applied Exercise — price the three all-pair routes (lecture comparison)

Problem: rank the three ways to get all-pair shortest distances on a dense graph.

Final Extracted Output: ⟹ Floyd-Warshall wins on a dense graph. On a sparse graph the ranking inverts: Dijkstras win for , and applied P7’s Johnson’s extends the same to negative edges.

Applied Exercise — detect arbitrage (applied P6)

Problem: currencies; units of spent to get unit of . Decide in whether some chain of conversions makes a profit.

Final Extracted Output: run plain Floyd-Warshall on rates and read the diagonal, . Alternative ➔ keep the raw rates and swap for ; arbitrage iff a diagonal entry is .

  • The modelling move ➔ a product objective becomes a sum under , so a shortest-path algorithm runs unmodified — transform the input, not the algorithm.

⚠️ Common Mistakes

  • 💡 Nesting the loops i, j, k ➔ the outer loop is the set of permitted intermediates; any other order breaks the DP layering and needs repeated passes to converge.
  • 💡 “Floyd-Warshall handles negative cycles” ➔ it detects them, on the diagonal. Distances through a negative cycle are , not numbers.
  • 💡 Using it on a sparse graph ➔ is paid even when ; the selection rule is density, and quoting it without naming the density is an LO3 mark loss (Graph §3) · sparse with negatives: Johnson’s.
  • 💡 Quoting for the time ➔ that is the space. Three loops, time, space — state both, and say the matrix may be input rather than auxiliary.
  • 💡 Confusing closure with connectivity ➔ the transitive closure is a directed reachability relation; does not give unless the graph is undirected.

🧠 Active Recall