Algorithm Search⌘K

Proofs: Yen's algorithm

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

Yen's algorithm lists the k shortest simple paths in order full

This proof shows: correctness, termination.

Let GG be a directed graph with nonnegative weights (parallel arcs merged to the lightest, self-loops dropped), and s,ts, t vertices. A path means a simple path from ss to tt, written as its list of vertices indexed from 0. For a path pp, p[0..i]p[0..i] is its prefix with i+1i + 1 vertices. Line numbers refer to YEN on the main page. Let Ak={A1,…,Ak}\mathcal{A}_k = \{A_1, \ldots, A_k\}.

Fact 1 (candidates are new simple paths). Every path added to BB at line L9 is a simple ss-tt path, and when it is added it is not in AA.

Proof. The candidate is the root Ak−1[0..i]A_{k-1}[0..i] followed by a spur path PP from the spur vertex Ak−1[i]A_{k-1}[i] to tt. The root is simple, as a prefix of a simple path. PP is a shortest path found by Dijkstra, so it is simple, and by line L7 it avoids the root vertices other than the spur. So the candidate is simple and ends at tt. Line L9 skips paths that are already in AA or BB. □\square

Fact 2 (weights). The key of a candidate in BB is its weight, and Dijkstra at line L8 returns a lightest spur path in the graph with the blocked arcs and vertices removed.

Proof. The weights are nonnegative, and Dijkstra is correct on such graphs. The key is the weight of the root plus the weight of the spur path. □\square

Lemma 3 (every other path has a cheaper candidate in BB). At line L11 in round kk, for every path P∉Ak−1P \notin \mathcal{A}_{k-1}, the queue BB contains a path CC with w(C)≤w(P)w(C) \le w(P).

Proof. For q∈Ak−1q \in \mathcal{A}_{k-1}, let ℓ(q)\ell(q) be the number of leading vertices that qq and PP have in common. Both start with ss, so ℓ(q)≥1\ell(q) \ge 1. Let L=max⁡qℓ(q)L = \max_q \ell(q), and let jj be the largest index with ℓ(Aj)=L\ell(A_j) = L. Set i=L−1i = L - 1, so P[0..i]=Aj[0..i]P[0..i] = A_j[0..i] and P[i+1]≠Aj[i+1]P[i+1] \ne A_j[i+1] or one of them ends at index ii. Neither path can end at index ii unless both do: a path that ends there ends at tt, and the other path, being simple, contains tt only as its last vertex, so it would end there too and they would be equal, but P≠AjP \ne A_j. So i≤∣Aj∣−2i \le |A_j| - 2 and P[i+1]≠Aj[i+1]P[i+1] \ne A_j[i+1].

Spur ii of AjA_j was computed in round j+1≤kj + 1 \le k (rounds 2,…,k2, \ldots, k compute the spurs of A1,…,Ak−1A_1, \ldots, A_{k-1}). In that round, line L6 blocked the arcs (P[i],q[i+1])(P[i], q[i+1]) for the paths q∈Ajq \in \mathcal{A}_j with q[0..i]=P[0..i]q[0..i] = P[0..i]. The arc (P[i],P[i+1])(P[i], P[i+1]) is not among them: if q[i+1]=P[i+1]q[i+1] = P[i+1] for such a qq, then ℓ(q)≥L+1\ell(q) \ge L + 1, which contradicts the choice of LL. Line L7 blocked P[0..i−1]P[0..i-1], and the part P[i..]P[i..] avoids these vertices, because PP is simple. So P[i..]P[i..] is a spur path in the graph of line L8, and by Fact 2 Dijkstra found a spur path of weight at most w(P[i..])w(P[i..]). The resulting path C=P[0..i]C = P[0..i] followed by that spur path has w(C)≤w(P)w(C) \le w(P).

CC was added to BB then, or it was already in AA or BB. It is not in Ak−1\mathcal{A}_{k-1}: since C[0..i]=P[0..i]C[0..i] = P[0..i] and C[i+1]C[i+1] is not blocked, CC differs from every q∈Ajq \in \mathcal{A}_j with that prefix, and paths in Aj\mathcal{A}_j without that prefix differ from CC anyway; and if C=AlC = A_l with j<l≤k−1j < l \le k - 1, then ℓ(Al)≥L\ell(A_l) \ge L, so ℓ(Al)=L\ell(A_l) = L with l>jl > j, against the choice of jj. Paths leave BB only at line L12, into AA, so CC is still in BB. □\square

Theorem. YEN returns distinct simple ss-tt paths A1,…,Ak′A_1, \ldots, A_{k'}, with k′=min⁡(K,N)k' = \min(K, N) where NN is the number of simple ss-tt paths, such that for every jj, AjA_j is a lightest path outside Aj−1\mathcal{A}_{j-1}. In particular w(A1)≤⋯≤w(Ak′)w(A_1) \le \cdots \le w(A_{k'}).

Proof. If tt is not reachable, there is no path, N=0N = 0, and line L1 returns the empty list. Otherwise A1A_1 is a shortest ss-tt path from Dijkstra, a simple path of least weight among all walks and so among all paths.

In round kk, by Fact 1 every element of BB is a path outside Ak−1\mathcal{A}_{k-1}. If some path PP lies outside Ak−1\mathcal{A}_{k-1}, Lemma 3 says BB is not empty, so line L11 does not stop, and line L12 takes AkA_k with w(Ak)≤w(C)≤w(P)w(A_k) \le w(C) \le w(P). So AkA_k is a lightest path outside Ak−1\mathcal{A}_{k-1}, and it is new. If no path lies outside Ak−1\mathcal{A}_{k-1}, then BB is empty by Fact 1 and line L11 returns, with k−1=Nk - 1 = N. Since Aj+1A_{j+1} is outside Aj\mathcal{A}_{j} and therefore outside Aj−1\mathcal{A}_{j-1}, the minimality of AjA_j gives w(Aj)≤w(Aj+1)w(A_j) \le w(A_{j+1}). □\square

Termination. Each round runs at most n−1n - 1 spur computations, each a run of Dijkstra, which terminates. There are at most K−1K - 1 rounds. ■\blacksquare

Back to Yen's algorithm