Tutorials › Graph Theory (Undergraduate) › The Floyd-Warshall Intermediate-Vertex Recurrence

Shortest Paths · Tutorial 251 of 799

The Floyd-Warshall Intermediate-Vertex Recurrence

Learn how limiting the allowed intermediate vertices produces the Floyd–Warshall table and why each entry updates by a minimum of two costs.

Intermediate 10 min read

What You'll Learn

  • Define shortest-path distances when internal vertices are restricted to an ordered set.
  • Initialize the Floyd–Warshall distance table from a directed weighted graph.
  • Derive and prove the intermediate-vertex recurrence.
  • Trace every update in small examples, including negative edges and unreachable pairs.
  • Recognize why the no-negative-cycle assumption matters for finite shortest distances.

Restricting Which Vertices a Path May Use

Single-source methods organize shortest paths around a starting vertex. The Floyd–Warshall method instead builds an all-pairs table in stages: at stage \(k\), it allows paths to use one more vertex as an internal vertex. The key observation is that a shortest path either avoids this newly allowed vertex or passes through it, in which case its cost splits into two shorter costs.

Throughout, let \(G\) be a finite directed graph with no loops or parallel arcs, and assign a real weight \(w_{ij}\) to each arc \(i\to j\). Negative edge weights are allowed. Assume that \(G\) has no directed cycle of negative total weight. This assumption ensures that shortest-walk costs are finite whenever a destination is reachable. A walk's cost is the sum of the weights of its arcs; a path is a walk with no repeated vertices. The internal vertices of a walk are all its vertices except its first and last vertices.

Definition: Number the vertices \(1,\dots,n\), and let \(S_k=\{1,\dots,k\}\), with \(S_0=\varnothing\). For vertices \(i,j\), let \(D^{(k)}_{ij}\) be the minimum cost of a walk from \(i\) to \(j\) whose internal vertices all belong to \(S_k\). Set \(D^{(k)}_{ij}=+\infty\) if there is no such walk. The walk of length zero from a vertex to itself is allowed, so \(D^{(k)}_{ii}\leq 0\); under the no-negative-cycle assumption, it equals \(0\).

The index \(k\) records which vertices are permitted internally, not how many edges a path may use. In particular, the endpoints \(i\) and \(j\) are not restricted by \(S_k\). This distinction matters when an endpoint itself has an index larger than \(k\).

Why Shortest Paths Can Be Chosen Without Repeated Vertices

Lemma: If a finite directed weighted graph has no negative-weight directed cycle, then whenever a walk from \(i\) to \(j\) exists, a minimum-cost such walk exists that is a path. The same holds when the internal vertices are restricted to any fixed set.

Proof. Any walk with a repeated vertex contains a nonempty closed subwalk between two occurrences of that vertex. A closed directed walk can be split into directed cycles by repeatedly splitting it at repeated vertices. Since the graph has no negative-weight directed cycle, each of those cycles has nonnegative cost, so the closed subwalk has nonnegative cost. Removing it leaves a walk with the same endpoints, no greater cost, and fewer arcs. Repeating this removal gives a path. There are only finitely many paths in a finite graph, so among the paths satisfying the internal-vertex restriction, a minimum-cost one exists whenever that set of paths is nonempty. Removing a closed subwalk cannot introduce new internal vertices, so the restriction is preserved. \(\square\)

This lemma also covers \(i=j\): the length-zero walk has cost \(0\), and every nonempty closed walk has nonnegative cost. Thus the shortest cost from a vertex to itself is \(0\). The no-negative-cycle assumption is important: if a negative cycle can be reached and then left on a route to a destination, repeated trips around it make the walk costs arbitrarily small, so a finite minimum need not exist.

Initialization and the Intermediate-Vertex Recurrence

Definition: Initialize the table by setting \(D^{(0)}_{ii}=0\), \(D^{(0)}_{ij}=w_{ij}\) when the arc \(i\to j\) exists, and \(D^{(0)}_{ij}=+\infty\) when \(i\ne j\) and there is no such arc. At stage \(0\), no internal vertices are permitted, so a walk with distinct endpoints can use only a single arc.

When vertex \(k\) becomes available internally, a shortest path either avoids \(k\), leaving its cost at \(D^{(k-1)}_{ij}\), or uses \(k\). In the latter case, the path can be split at \(k\): the part from \(i\) to \(k\) and the part from \(k\) to \(j\) use only vertices in \(S_{k-1}\) internally.

Theorem (Floyd–Warshall recurrence): Under the no-negative-cycle assumption, for every \(k=1,\dots,n\) and every pair \(i,j\), $$ D^{(k)}_{ij} = \min\!\left(D^{(k-1)}_{ij},\; D^{(k-1)}_{ik}+D^{(k-1)}_{kj}\right). $$ Use the conventions \(+\infty+x=+\infty\) for finite \(x\), and \(\min(x,+\infty)=x\).

Proof. Fix \(k,i,j\). First consider any walk from \(i\) to \(j\) whose internal vertices belong to \(S_k\). By the lemma, a minimum-cost such walk can be chosen to be a path. If this path does not have \(k\) as an internal vertex, then its internal vertices belong to \(S_{k-1}\), so its cost is at least \(D^{(k-1)}_{ij}\). If it does have \(k\) internally, the path visits \(k\) exactly once. Splitting at \(k\) gives an \(i\)-to-\(k\) path and a \(k\)-to-\(j\) path whose internal vertices lie in \(S_{k-1}\). Their costs are at least \(D^{(k-1)}_{ik}\) and \(D^{(k-1)}_{kj}\), respectively. Thus the minimum cost allowed at stage \(k\) is at least the stated minimum.

For the reverse inequality, a walk achieving \(D^{(k-1)}_{ij}\), when finite, is still allowed at stage \(k\). Also, if both \(D^{(k-1)}_{ik}\) and \(D^{(k-1)}_{kj}\) are finite, concatenate paths achieving them. The resulting walk has internal vertices in \(S_k\), so its cost \(D^{(k-1)}_{ik}+D^{(k-1)}_{kj}\) is an available cost at stage \(k\). Therefore \(D^{(k)}_{ij}\) is no greater than either finite candidate. If a candidate is infinite, it supplies no route and does not affect the minimum. Combining the two inequalities proves the recurrence. \(\square\)

The proof includes endpoint cases. For example, if \(i=k\), the candidate through \(k\) uses \(D^{(k-1)}_{kk}=0\), so it does not create a spurious improvement. Every stage uses the previous stage's entries; conceptually, all entries for one \(k\) are updated from the same table \(D^{(k-1)}\).

Worked Tables

Worked Example: A Two-Vertex Initialization

Let \(V=\{1,2\}\), with the single arc \(1\to2\) of weight \(5\). There is no directed cycle, so the standing assumption holds. The initial table is

$$ D^{(0)}= \begin{pmatrix} 0&5\\ +\infty&0 \end{pmatrix}. $$

At \(k=1\), the through-1 candidate matrix has entries \(D^{(0)}_{i1}+D^{(0)}_{1j}\): its first row is \(0+0=0\), \(0+5=5\), and its second row is \(+\infty+0=+\infty\), \(+\infty+5=+\infty\). Taking the minimum with \(D^{(0)}\) leaves \(D^{(1)}=D^{(0)}\).

At \(k=2\), the candidates are \(0+(+\infty)=+\infty\), \(0+0=0\), \(5+(+\infty)=+\infty\), and \(5+0=5\), in row order. Again \(D^{(2)}=D^{(1)}\). In particular, the candidate from \(2\) to \(2\) is \(D^{(1)}_{22}+D^{(1)}_{22}=0+0=0\), so the diagonal entry remains zero.

Check: The only path between distinct vertices is the arc \(1\to2\), of cost \(5\); there is no path from \(2\) to \(1\). The final table records exactly these costs and the two length-zero costs.

Worked Example: A Negative Edge Without a Negative Cycle

Let \(V=\{1,2,3\}\) and let the arcs be \(1\to2\) of weight \(4\), \(1\to3\) of weight \(10\), \(2\to3\) of weight \(-2\), and \(3\to1\) of weight \(3\). The directed cycle \(1\to2\to3\to1\) has weight \(4+(-2)+3=5\), so it is not negative; there are no other directed cycles. The initial table is

$$ D^{(0)}= \begin{pmatrix} 0&4&10\\ +\infty&0&-2\\ 3&+\infty&0 \end{pmatrix}. $$

For \(k=1\), the candidate matrix \(D^{(0)}_{i1}+D^{(0)}_{1j}\) is \(\begin{pmatrix}0&4&10\\+\infty&+\infty&+\infty\\3&7&13\end{pmatrix}\). For example, the candidate from \(3\) to \(2\) is \(3+4=7\), and the candidate from \(3\) to \(3\) is \(3+10=13\). Taking entrywise minima gives

$$ D^{(1)}= \begin{pmatrix} 0&4&10\\ +\infty&0&-2\\ 3&7&0 \end{pmatrix}. $$

For \(k=2\), the candidate matrix, computed from \(D^{(1)}\), is \(\begin{pmatrix}+\infty&4&2\\+\infty&0&-2\\+\infty&7&5\end{pmatrix}\). The new candidate from \(1\) to \(3\) is \(D^{(1)}_{12}+D^{(1)}_{23}=4+(-2)=2\), which improves \(10\). The candidate from \(3\) to \(3\) is \(7+(-2)=5\), which does not improve \(0\). Thus

$$ D^{(2)}= \begin{pmatrix} 0&4&2\\ +\infty&0&-2\\ 3&7&0 \end{pmatrix}. $$

For \(k=3\), the candidate matrix is \(\begin{pmatrix}5&9&2\\1&5&-2\\3&7&0\end{pmatrix}\). For instance, the candidate from \(2\) to \(1\) is \((-2)+3=1\), improving \(+\infty\); the candidate from \(1\) to \(1\) is \(2+3=5\), which does not improve \(0\). Entrywise minimization gives

$$ D^{(3)}= \begin{pmatrix} 0&4&2\\ 1&0&-2\\ 3&7&0 \end{pmatrix}. $$

Check: The improved route from \(1\) to \(3\) is \(1\to2\to3\), with cost \(4+(-2)=2\). The route from \(2\) to \(1\) is \(2\to3\to1\), with cost \((-2)+3=1\). The route from \(3\) to \(2\) is \(3\to1\to2\), with cost \(3+4=7\). These costs agree with the corresponding final entries.

Worked Example: An Unreachable Vertex and a Negative Arc

Let \(V=\{a,b,c\}\), with arcs \(a\to b\) of weight \(2\), \(b\to a\) of weight \(-1\), and \(a\to c\) of weight \(4\). The only directed cycle has weight \(2+(-1)=1\), so there is no negative cycle. With vertex order \(a,b,c\),

$$ D^{(0)}= \begin{pmatrix} 0&2&4\\ -1&0&+\infty\\ +\infty&+\infty&0 \end{pmatrix}. $$

At \(k=a\), the candidate matrix is \(\begin{pmatrix}0&2&4\\-1&1&3\\+\infty&+\infty&+\infty\end{pmatrix}\). The candidate \(b\)-to-\(c\) cost is \((-1)+4=3\), so \(D^{(1)}_{bc}=3\); the candidate \(b\)-to-\(b\) cost is \((-1)+2=1\), which does not improve its current value \(0\). Hence \(D^{(1)}=\begin{pmatrix}0&2&4\\-1&0&3\\+\infty&+\infty&0\end{pmatrix}\).

At \(k=b\), the candidate matrix is \(\begin{pmatrix}1&2&5\\-1&0&3\\+\infty&+\infty&+\infty\end{pmatrix}\). The candidate \(a\)-to-\(a\) cost is \(2+(-1)=1\), so its entry stays \(0\); the candidate \(a\)-to-\(c\) cost is \(2+3=5\), so its entry stays \(4\). At \(k=c\), every candidate starting at \(c\) and ending at \(a\) or \(b\) is \(0+(+\infty)=+\infty\); the other candidates do not improve the table. Thus the final table is \(D^{(2)}=D^{(3)}=D^{(1)}\).

Check: The route \(b\to a\to c\) costs \((-1)+4=3\), as recorded. No route leaves \(c\), so \(c\)-to-\(a\) and \(c\)-to-\(b\) remain \(+\infty\). The direct route \(a\to c\) costs \(4\), less than the alternative \(a\to b\to a\to c\), whose cost is \(2+(-1)+4=5\).

Reading the Table and Avoiding Common Errors

After stage \(k\), the entry \(D^{(k)}_{ij}\) represents the best cost among routes whose internal vertices lie in \(\{1,\dots,k\}\). Once all vertices have been admitted, \(D^{(n)}\) is the all-pairs distance table under the stated no-negative-cycle assumption. The vertex order determines the intermediate tables, but the final restriction includes every vertex, so the final entries represent unrestricted shortest distances.

A common mistake is to confuse the index of the newly allowed intermediate vertex with an endpoint, or to use entries from the wrong stage. The update for stage \(k\) always uses \(D^{(k-1)}_{ik}\) and \(D^{(k-1)}_{kj}\); it does not use an arbitrary direct edge or an entry from a later stage. For a diagonal update such as \(i=j=k\), the candidate is \(D^{(k-1)}_{kk}+D^{(k-1)}_{kk}=0+0=0\), not a sum involving unrelated entries. Another frequent error is treating \(+\infty\) as an ordinary real number: it records that a route is unavailable, and adding it to a finite cost still gives \(+\infty\).

The recurrence is the structural reason the method is compact: every new table is obtained by comparing a route that avoids \(k\) with one that passes through \(k\). The proof establishes the meaning of each restricted table entry; further questions, including how negative cycles affect the computation, require separate care.

Check Your Understanding

Use the intermediate-vertex definition and recurrence to answer the following.

  1. In the recurrence, why are both subpath entries taken from \(D^{(k-1)}\), rather than from a table that already allows \(k\)?
  2. Suppose \(D^{(k-1)}_{ik}=+\infty\) but \(D^{(k-1)}_{ij}\) is finite. What does the update imply for \(D^{(k)}_{ij}\)?
  3. For the graph in the negative-edge example, calculate the candidate for the \(1\)-to-\(3\) entry at \(k=2\) and state why it changes the entry.
  4. Explain why a negative edge does not by itself invalidate the recurrence, and identify the assumption used to guarantee minimum costs.
  5. Give a directed weighted graph with a negative cycle and explain why a finite shortest-walk cost may fail to exist.