Seyed Masoud Hosseini · Overview · Study log · Weekly summaries · Ideas · Search · Transcript · RSS feed

Design & Analysis of Algorithms · Lecture 15 of 34 · 1:21:49

11. Dynamic Programming: All-Pairs Shortest Paths

11. Dynamic Programming: All-Pairs Shortest Paths on YouTube

Study guide

What this lecture covers

The lecture answers a single question: given a directed graph with weighted edges (possibly negative), how do you find the shortest path between every pair of vertices, faster than just running a single-source algorithm from each vertex in turn? It follows the earlier lecture on dynamic programming and precedes further graph algorithms in MIT's 6.046 course, building on single-source shortest-path algorithms (BFS, Dijkstra, Bellman-Ford) that students are assumed to already know.

By the end, you can derive two dynamic-programming formulations of all-pairs shortest paths, connect one of them to matrix multiplication and repeated squaring, state and apply the Floyd-Warshall algorithm, and explain how Johnson's algorithm reweights edges so that Dijkstra can be run safely even when the original graph has negative edge weights.

Key ideas

  • All-pairs vs. single-source: all-pairs shortest paths asks for the distance Delta(u, v) between every pair of vertices, not just from one source; it's motivated by pre-computing distances for fast repeated queries, such as a mapping service.
  • Naive baseline: running a single-source algorithm from every vertex gives V^2 (BFS), V^2 log V + VE (Dijkstra), or V^2 E (Bellman-Ford); the last case can cost as much as V^4 in dense graphs.
  • DP1 (edge-count parameterization): define d(u, v, m) as the shortest path from u to v using at most m edges, guess the last edge, and relax; this runs in V^4 time, no better than repeated Bellman-Ford.
  • Relaxation: every shortest-path algorithm in the lecture repeatedly enforces the triangle inequality d(u,v) <= d(u,x) + d(x,v), updating d(u,v) downward when it's violated.
  • Matrix multiplication connection: replacing + with min and * with + (a semiring the lecture calls 'circle world') turns the DP1 recurrence into circle-matrix multiplication, and repeated squaring computes it in V^3 log V.
  • Floyd-Warshall: redefines subproblems as C(u, v, k), the shortest path using only intermediate vertices 1..k; guessing only whether vertex k is used (not where) gives a V^3 algorithm with no log factor.
  • Johnson's algorithm: reweights edges using a height function h so all weights become non-negative, then runs Dijkstra from every vertex; the height function itself comes from running Bellman-Ford once from an added zero-weight source vertex.
  • Negative-weight cycles: all-pairs algorithms can detect them (a negative value on the diagonal of the distance matrix, or Bellman-Ford failing to satisfy the difference constraints used to build Johnson's height function).

Walkthrough

Recap of single-source algorithms (0:00)

The lecture opens by reviewing the running times of single-source shortest-path algorithms across four scenarios: unweighted graphs (BFS, V+E), non-negative weights (Dijkstra, V log V + E), general weights (Bellman-Ford, VE), and DAGs (one pass of Bellman-Ford after a topological sort, linear time). These numbers become the baseline for comparison throughout the lecture.

Defining all-pairs shortest paths (7:06)

Delta(s, v) is defined as the weight of the shortest path from s to v, which can be infinite (no path) or negative infinity (a reachable negative-weight cycle). The all-pairs problem asks for Delta(u, v) for every pair, motivated by applications like pre-computing distances between major cities or routing tables, where queries need to be answered quickly and often.

Naive results and the target bound (11:13)

Running each single-source algorithm from every vertex gives baseline running times, the worst being V^2 E (up to V^4 in dense graphs) for general weights via Bellman-Ford. The lecture names Johnson's algorithm as the target: it matches the cost of running Dijkstra V times (V^2 log V + VE) even when the graph has negative weights, which is presented as a surprising result given that Dijkstra alone can't handle negative weights.

DP1: parameterizing by number of edges (15:25)

Following a five-step recipe for dynamic programs (subproblems, guessing, recurrence, acyclic order, final answer), the lecture defines d(u, v, m) as the shortest path from u to v using at most m edges. Guessing the last edge on the path gives the recurrence d(u,v,m) = min over x of d(u,x,m-1) + w(x,v), with base case d(u,u,0) = 0 and infinity otherwise. Written as nested loops, this is a relaxation step identical in spirit to Dijkstra and Bellman-Ford, and it runs in V^4 time — no improvement yet, but it sets up the next idea.

Matrix multiplication and repeated squaring (35:05)

The DP1 recurrence is shown to be exactly matrix multiplication if addition is replaced by min and multiplication by +. Under this reinterpretation, computing d(*, *, m) for all m up to n-1 is equivalent to computing w raised to a 'circle power'. Naively that takes n matrix multiplications (V^4 again), but repeated squaring reaches the same result in only log n multiplications, giving V^3 log V. The lecture notes this semiring lacks subtraction, so faster matrix-multiplication algorithms (Strassen and its successors) don't apply here, though they do apply to a related problem, transitive closure.

Floyd-Warshall algorithm (49:24)

A different subproblem definition removes the log factor. C(u, v, k) is the shortest path from u to v using only intermediate vertices numbered 1 through k. Instead of guessing which vertex comes last (n choices), the algorithm guesses only whether vertex k is used at all (2 choices): C(u,v,k) = min(C(u,v,k-1), C(u,k,k-1) + C(k,v,k-1)). This constant-time recurrence per subproblem yields a V^3 algorithm, described as about five lines of code and the standard choice for dense graphs.

Johnson's algorithm (59:48)

For sparse graphs, Johnson's algorithm gets closer to V^2 log V + VE. It reweights each edge (u,v) to w(u,v) + h(u) - h(v) for some height function h, chosen so all new weights are non-negative; the lecture proves that this reweighting shifts every path between two fixed endpoints by the same fixed amount, so shortest paths are preserved. Finding a valid h is shown to be equivalent to solving a system of difference constraints, which has a solution exactly when the graph has no negative-weight cycle. The construction adds a new source vertex with zero-weight edges to every other vertex, runs Bellman-Ford once from it to get h, reweights all edges, then runs Dijkstra from every vertex and translates the results back to the original weights.

Before you watch

  • Know Dijkstra's algorithm, Bellman-Ford, and BFS for single-source shortest paths, and the definition of the triangle inequality for shortest-path weights.
  • Be comfortable with the standard dynamic-programming recipe (subproblems, guessing, recurrence, base cases, evaluation order).
  • Some familiarity with matrix multiplication and repeated squaring for exponentiation is useful for the middle section.

Check your understanding

  1. Why does the naive DP1 formulation (parameterizing by number of edges used) take V^4 time, and what does redefining the subproblem in Floyd-Warshall change to bring that down to V^3?
  2. In Johnson's algorithm, why must the height function h satisfy w(u,v) + h(u) - h(v) >= 0 for every edge, and how does the proof show that shortest paths are preserved under this reweighting?
  3. Why does a negative-weight cycle make the system of difference constraints unsolvable, and how does the lecture use Bellman-Ford to detect this?
  4. What property of the 'circle world' semiring (min-plus) prevents Strassen-style fast matrix multiplication from being applied to speed up the DP1/matrix-multiplication approach?

Vocabulary

shortest path (noun)
The lowest-cost route between two points in a graph.
Dijkstra's algorithm finds the shortest path from one starting point.
all-pairs shortest paths (noun)
The problem of finding the shortest distance between every pair of points in a graph.
All-pairs shortest paths gives a full table of distances at once.
directed graph (noun)
A graph where connections between points only go one way.
In a directed graph, an edge from A to B doesn't imply one from B to A.
negative-weight cycle (noun)
A loop in a graph whose total edge weight is less than zero.
A negative-weight cycle makes shortest paths undefined.
relaxation (noun)
A step that updates a distance estimate if a shorter path is found.
Relaxation repeatedly improves the current best distance estimate.
triangle inequality (noun)
The rule that going directly between two points is never longer than going through a third point.
Shortest-path algorithms enforce the triangle inequality at every step.
repeated squaring (noun)
A technique that computes a large power quickly by repeatedly squaring intermediate results.
Repeated squaring reduces the number of matrix multiplications needed.
semiring (noun)
A mathematical structure with two operations, similar to addition and multiplication, but without needing subtraction.
The min-plus semiring replaces normal addition and multiplication.
reweighting (noun)
Adjusting all the weights in a graph in a way that preserves shortest paths.
Reweighting removes negative edges so Dijkstra can be used safely.
height function (noun)
A value assigned to each vertex used to adjust edge weights consistently.
The height function makes every edge weight non-negative after reweighting.
difference constraint (noun)
A condition limiting how much two values can differ from each other.
Finding a valid height function means solving a set of difference constraints.
dense graph (adjective)
A graph with a large number of edges relative to its number of vertices.
Floyd-Warshall works well on a dense graph.
sparse graph (adjective)
A graph with relatively few edges compared to its number of vertices.
Johnson's algorithm performs better on a sparse graph.
baseline (noun)
A starting reference point used to measure improvement against.
The naive results serve as a baseline for the rest of the lecture.
recipe (DP) (noun)
A standard step-by-step method used to build a dynamic-programming solution.
The lecture follows a five-step recipe for dynamic programs.
intermediate vertex (noun)
A vertex that lies somewhere along a path, between its start and end.
Floyd-Warshall limits paths to certain allowed intermediate vertices.
transitive closure (noun)
A structure showing which vertices can reach which others in a graph, ignoring distance.
Fast matrix multiplication does apply to transitive closure.
pre-compute (verb)
To calculate something in advance, before it is actually needed.
A mapping service might pre-compute distances between major cities.
translate back (phrasal verb)
To convert a result back into its original form or units.
The algorithm translates the reweighted results back to original weights.
system of constraints (noun)
A group of conditions that must all be satisfied at once.
Finding a valid height function means solving a system of constraints.
surprising (adjective)
Unexpected, going against what you would normally assume.
It is surprising that Dijkstra's speed can be matched despite negative weights.
nested loops (phrase)
A loop placed inside another loop.
The recurrence is written as nested loops over every vertex pair.
successors (noun)
Later versions or improvements that follow an original idea.
Strassen's algorithm and its successors don't help with this semiring.
scenario (noun)
A particular set of circumstances being considered.
The lecture reviews running times across four different scenarios.
routing table (noun)
A stored list showing the best path for data to travel through a network.
All-pairs shortest paths can help build a routing table.

From the YouTube description

MIT 6.046J Design and Analysis of Algorithms, Spring 2015
View the complete course: http://ocw.mit.edu/6-046JS15
Instructor: Erik Demaine

In this lecture, Professor Demaine covers different algorithmic solutions for the All-Pairs Shortest Paths problem.

License: Creative Commons BY-NC-SA
More information at http://ocw.mit.edu/terms
More courses at http://ocw.mit.edu

← Lecture 10: Dynamic Programming: Advanced DP · 12. Greedy Algorithms: Minimum Spanning Tree →