Algorithm Search⌘K

Proofs: Shortest Path Faster Algorithm

These are the human proofs of Shortest Path Faster Algorithm, at full length.

SPFA returns the distances or reports a reachable negative cycle full

This proof shows: correctness, termination.

Let G=(V,E)G = (V, E) have nn vertices, real weights ww and source ss. Line numbers refer to the pseudocode of SPFA on the main page. A label change is one execution of line L7.

Walks behind the labels. Attach to each vertex vv with d(v)<∞d(v) < \infty a walk W(v)W(v) from ss to vv: at the start W(s)=⟨s⟩W(s) = \langle s \rangle, and at each label change of vv through the arc (u,v)(u, v), set W(v)W(v) to the current W(u)W(u) followed by (u,v)(u, v). These walks are only for the proof.

Fact 1. At all times, for every vv with d(v)<∞d(v) < \infty, d(v)=w(W(v))d(v) = w(W(v)) and k(v)k(v) is the number of arcs of W(v)W(v).

Proof. True at the start, since d(s)=0=w(⟨s⟩)d(s) = 0 = w(\langle s \rangle) and k(s)=0k(s) = 0. A label change of vv sets d(v)=d(u)+w(u,v)d(v) = d(u) + w(u, v) and k(v)=k(u)+1k(v) = k(u) + 1, which by induction are the weight and the arc count of W(u)W(u) followed by (u,v)(u, v). Other labels do not change. □\square

Fact 2. Labels only decrease, and each label change of vv makes d(v)d(v) strictly smaller.

Proof. Line L7 runs only when the test of line L6 holds. □\square

Lemma 1 (repeated vertices). If at some time W(v)=⟨v0,…,vk⟩W(v) = \langle v_0, \ldots, v_k \rangle has vi=vjv_i = v_j with i<ji < j, then the closed walk ⟨vi,…,vj⟩\langle v_i, \ldots, v_j \rangle has negative weight, and it is reachable from ss.

Proof. By construction, the prefix Pℓ=⟨v0,…,vℓ⟩P_\ell = \langle v_0, \ldots, v_\ell \rangle of W(v)W(v) was the walk W(vℓ)W(v_\ell) at some time tℓt_\ell, and w(Pℓ)w(P_\ell) was the label d(vℓ)d(v_\ell) at that time, by Fact 1. Here tℓt_\ell is the time of the label change that created W(vℓ)W(v_\ell), or the start for ℓ=0\ell = 0, and t0<t1<⋯<tkt_0 < t_1 < \cdots < t_k, because W(vℓ+1)W(v_{\ell+1}) was built from the walk W(vℓ)W(v_\ell) that existed at that moment. The vertex x=vi=vjx = v_i = v_j has a label change at time tj>tit_j > t_i (if j≥1j \ge 1, then tjt_j is a label change). By Fact 2, the label of xx after time tjt_j is strictly smaller than its label just before tjt_j, which is at most its label at time tit_i. So w(Pj)<w(Pi)w(P_j) < w(P_i). Since PjP_j is PiP_i followed by the closed walk C=⟨vi,…,vj⟩C = \langle v_i, \ldots, v_j \rangle, w(C)=w(Pj)−w(Pi)<0w(C) = w(P_j) - w(P_i) < 0. CC starts at viv_i, which PiP_i reaches from ss. □\square

A negative closed walk contains a negative cycle (see negative cycle), so we get:

Corollary 1. If line L8 returns "negative cycle", then a negative cycle is reachable from ss.

Proof. At that moment k(v)≥nk(v) \ge n, so W(v)W(v) has at least n+1n + 1 vertices by Fact 1 and repeats one. Apply Lemma 1. □\square

Lemma 2 (queue invariant). At the test of line L3, every arc (u,v)(u, v) with d(u)<∞d(u) < \infty and d(u)+w(u,v)<d(v)d(u) + w(u, v) < d(v) has uu in QQ.

Proof. At the start only d(s)d(s) is finite, and ss is in QQ. Consider one iteration that dequeues uu. Line L5 scans every arc out of uu, and after its relaxation each such arc (u,v)(u, v) satisfies d(v)≤d(u)+w(u,v)d(v) \le d(u) + w(u, v); later relaxations in the same scan only lower other labels d(v′)d(v') with v′≠uv' \ne u, or lower d(u)d(u) itself through a self-loop. In the last case line L9 puts uu back in QQ. Every vertex vv whose label goes down is in QQ after line L9, which covers the arcs out of vv that may now be violated. Lowering d(v)d(v) cannot violate an arc into vv. So the invariant holds again at the next test. □\square

Lemma 3 (termination). SPFA terminates.

Proof. While line L8 has not returned, every k(v)≤n−1k(v) \le n - 1, so by Fact 1 every finite label is the weight of a walk from ss with at most n−1n - 1 arcs. There are finitely many such walks, so the labels take values in a finite set. By Fact 2 each vertex has finitely many label changes, and so line L9 adds finitely many vertices to QQ. Each iteration of line L3 removes one vertex from QQ, so the loop ends. □\square

Theorem. If a negative cycle is reachable from ss, SPFA returns "negative cycle". Otherwise it returns d(v)=δ(s,v)d(v) = \delta(s, v) for every vv, with d(v)=∞d(v) = \infty exactly when vv is not reachable from ss, and π\pi is a shortest-path tree.

Proof. By Lemma 3, SPFA either returns at line L8 or reaches line L10 with QQ empty. Suppose it reaches line L10. By Fact 1 only reachable vertices have finite labels, and every reachable vertex has one: along a path from ss, an arc (u,v)(u, v) with d(u)<∞=d(v)d(u) < \infty = d(v) would be violated, against Lemma 2. So, by Lemma 2, d(v)≤d(u)+w(u,v)d(v) \le d(u) + w(u, v) holds on every arc whose tail is reachable.

No negative cycle is reachable. Let C=⟨c0,…,cℓ=c0⟩C = \langle c_0, \ldots, c_\ell = c_0 \rangle be a cycle through a reachable vertex. All its vertices are reachable, so their labels are real, and summing d(ci)≤d(ci−1)+w(ci−1,ci)d(c_i) \le d(c_{i-1}) + w(c_{i-1}, c_i) over i=1,…,ℓi = 1, \ldots, \ell gives 0≤w(C)0 \le w(C).

The labels are the distances. The label d(s)d(s) never changed: a change would make d(s)<0d(s) < 0 the weight of a closed walk from ss by Fact 1, a negative closed walk reachable from ss, which contains a negative cycle reachable from ss. So d(s)=0d(s) = 0, each finite label is the weight of a walk from ss, and the triangle inequality holds on every arc with a reachable tail. Theorem B of the optimality conditions gives d=δ(s,⋅)d = \delta(s, \cdot).

So if a negative cycle is reachable from ss, SPFA cannot reach line L10, and it returns "negative cycle". If no negative cycle is reachable, Corollary 1 shows that line L8 never returns, and the run ends at line L10 with the distances. For the tree: each parent arc (π(v),v)(\pi(v), v) was tight when it was set, d(π(v))d(\pi(v)) can only have gone down since then, and by the optimality conditions it cannot go below d(v)−w(π(v),v)d(v) - w(\pi(v), v); so every parent arc is tight at the end, and with the distances final, the parents form a shortest-path tree by its predecessor-subgraph property. □\square

Running time. Define passes: pass 0 is the dequeue of ss, and pass j+1j + 1 dequeues the vertices in QQ at the end of pass jj. Claim: a label set during pass jj has k(v)≥j+1k(v) \ge j + 1. For j=0j = 0, k(s)=0k(s) = 0, so k(v)=1k(v) = 1. For pass j≥1j \ge 1, the dequeued vertex uu entered QQ during pass j−1j - 1, so its current label was set during pass j−1j - 1 or later, and k(u)≥jk(u) \ge j by induction on time; hence k(v)=k(u)+1≥j+1k(v) = k(u) + 1 \ge j + 1. So a label set during pass n−1n - 1 has k(v)≥nk(v) \ge n and line L8 returns. There are at most nn passes. Each vertex is in QQ at most once at a time, so it is dequeued at most once per pass, and a pass scans each arc at most once. The total time is O(n(n′+m))O(n(n' + m)), where n′≤min⁡(n,m+1)n' \le \min(n, m + 1) is the number of vertices reachable from ss, which is O(nm)O(nm). ■\blacksquare

Back to Shortest Path Faster Algorithm