Algorithm Search⌘K

Proofs: Kahn's algorithm

These are the human proofs of Kahn's algorithm, at full length.

Kahn's algorithm returns a topological ordering or detects a cycle full

This proof shows: correctness, termination.

Let G=(V,E)G = (V, E) be a directed graph with nn vertices, possibly with parallel edges and self-loops, where each copy of an edge is one entry of an adjacency list. For a set S⊆VS \subseteq V, write inS(v)\mathrm{in}_S(v) for the number of edges (u,v)(u, v) with u∉Su \notin S. Let LL also stand for the set of vertices in the list LL.

Invariant. At the start of each iteration of the loop of line L5, and when the loop ends:

  1. in[v]=inL(v)\mathrm{in}[v] = \mathrm{in}_L(v) for each v∉Lv \notin L;
  2. QQ holds, each one time, exactly the vertices v∉Lv \notin L with in[v]=0\mathrm{in}[v] = 0;
  3. for each edge (u,v)(u, v) with v∈Lv \in L, also u∈Lu \in L, and uu is before vv in LL.

Initialization. After line L2, in[v]\mathrm{in}[v] is the number of entries vv in all lists, the in-degree of vv, and LL is empty, so part 1 holds. Line L4 enqueues each vertex with in[v]=0\mathrm{in}[v] = 0 once, so part 2 holds. Part 3 holds because LL is empty.

Maintenance. Let one iteration dequeue uu. By part 2, u∉Lu \notin L and in[u]=0\mathrm{in}[u] = 0, so by part 1 each edge into uu comes from a vertex in LL. Line L6 appends uu to LL. Part 3 holds for the new LL: for edges (x,u)(x, u), xx is in the old LL and so before uu, and u≠xu \ne x because a self-loop (u,u)(u, u) would give inL(u)≥1\mathrm{in}_L(u) \ge 1. Edges into older vertices of LL are unchanged. For part 1, the new value of inL(v)\mathrm{in}_L(v) for v∉Lv \notin L is the old value minus the number of edges (u,v)(u, v), and lines L7 and L8 decrease in[v]\mathrm{in}[v] one time for each such entry of Adj[u]\mathrm{Adj}[u]. Entries vv that are already in LL are decreased too, but their counts are not used again. For part 2, a vertex v∉Lv \notin L whose count becomes zero in this iteration had a positive count before, so it was not in QQ, and line L9 enqueues it once, at the decrease that makes the count zero. A count that is already zero is never decreased again for v∉Lv \notin L, because a decrease of vv comes from an edge (u,v)(u, v) with u∉Lu \notin L, which part 1 counts. So no vertex is enqueued twice. The vertex uu left QQ and joined LL. So part 2 holds.

Termination. By part 2, each dequeued vertex joins LL and never returns to QQ, so the loop of line L5 runs at most nn times, and each iteration scans one finite list.

Lemma (remaining vertices). When the loop ends, let R=V∖LR = V \setminus L. If RR is not empty, then GG has a directed cycle all of whose vertices are in RR.

Proof. The queue is empty, so by part 2 each v∈Rv \in R has in[v]≠0\mathrm{in}[v] \ne 0, and by part 1 there is an edge (u,v)(u, v) with u∉Lu \notin L, that is, u∈Ru \in R. Start at some w0∈Rw_0 \in R, and choose wi+1∈Rw_{i+1} \in R with (wi+1,wi)∈E(w_{i+1}, w_i) \in E. Among w0,…,w∣R∣w_0, \ldots, w_{|R|} some vertex repeats, wi=wjw_i = w_j with i<ji < j, and wj,wj−1,…,wi+1w_j, w_{j-1}, \ldots, w_{i+1} with the edge (wi+1,wi)(w_{i+1}, w_i) is a directed cycle in RR. □\square

Theorem. KAHN(G)(G) terminates. If GG is acyclic, it returns a topological ordering. If GG has a directed cycle, it reports a cycle.

Proof. Termination was shown above.

If GG is acyclic, the lemma shows that RR is empty when the loop ends. So ∣L∣=n|L| = n, line L10 does not report, and LL holds each vertex once, by part 2. By part 3, applied with L=VL = V, each edge (u,v)(u, v) has uu before vv. So LL is a topological ordering.

If GG has a directed cycle CC, no vertex of CC is in LL at the end. Assume otherwise, and let xx be the vertex of CC appended to LL first, and ww the vertex before xx on CC, so (w,x)∈E(w, x) \in E. By part 3, at the iteration after xx joined LL, ww is in LL and before xx. If w=xw = x, this says xx is before itself, which is false. Otherwise ww is a vertex of CC appended before xx, which contradicts the choice of xx. So ∣L∣≤n−∣C∣<n|L| \le n - |C| < n, and line L10 reports a cycle. ■\blacksquare

Back to Kahn's algorithm