Algorithm Search⌘K

Proofs: Gabow's scaling algorithm

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

Gabow's scaling algorithm is correct full

This proof shows: correctness, termination.

Claim. Let every weight be an integer in 0…N0 \ldots N, and let bb be the number of bits of NN (b=0b = 0 if N=0N = 0). For 0≤i≤b0 \le i \le b, let wi(e)=⌊w(e)/2b−i⌋w_i(e) = \lfloor w(e) / 2^{b-i} \rfloor and let di(v)d_i(v) be the distance from ss to vv under wiw_i (+∞+\infty if ss does not reach vv). After line L1, d=d0d = d_0, and after the iteration ii of line L2, d=did = d_i. Since wb=ww_b = w, GABOW-SCALING returns δ(s,v)\delta(s, v) for every vv. It ends after bb iterations.

Reachability does not depend on the weights, so di(v)=∞d_i(v) = \infty for one ii exactly when it holds for all ii; call the other vertices reachable. All weights wiw_i are nonnegative integers, so there is no negative cycle, every di(v)d_i(v) for reachable vv is a nonnegative integer, and it is the weight of a simple path (deleting a cycle from a walk does not increase its weight).

Step 1: the rounding bounds. Write w(e)=q⋅2b−i+1+ρw(e) = q \cdot 2^{b-i+1} + \rho with 0≤ρ<2b−i+10 \le \rho < 2^{b-i+1}. Then wi−1(e)=qw_{i-1}(e) = q and wi(e)=2q+⌊ρ/2b−i⌋w_i(e) = 2q + \lfloor \rho / 2^{b-i} \rfloor with ⌊ρ/2b−i⌋∈{0,1}\lfloor \rho / 2^{b-i} \rfloor \in \{0, 1\}. So 2wi−1(e)≤wi(e)≤2wi−1(e)+12 w_{i-1}(e) \le w_i(e) \le 2 w_{i-1}(e) + 1.

Step 2: scale 0. w0=0w_0 = 0 on every edge (every weight is below 2b2^b), so d0(v)=0d_0(v) = 0 for every reachable vv, and line L1 sets exactly this.

Step 3: the reduced lengths are nonnegative. Assume d=di−1d = d_{i-1} at the start of iteration ii. For an edge (u,v)(u, v) with uu reachable, vv is reachable too, and di−1(v)≤di−1(u)+wi−1(u,v)d_{i-1}(v) \le d_{i-1}(u) + w_{i-1}(u, v). With Step 1, r(u,v)=wi(u,v)+2di−1(u)−2di−1(v)≥wi(u,v)−2wi−1(u,v)≥0r(u, v) = w_i(u, v) + 2 d_{i-1}(u) - 2 d_{i-1}(v) \ge w_i(u, v) - 2 w_{i-1}(u, v) \ge 0. Edges out of unreachable vertices are never scanned in line L5, because such a vertex never gets a finite label.

Step 4: reduced distances. For a path PP from ss to a reachable vv, the potentials telescope: r(P)=wi(P)+2di−1(s)−2di−1(v)=wi(P)−2di−1(v)r(P) = w_i(P) + 2 d_{i-1}(s) - 2 d_{i-1}(v) = w_i(P) - 2 d_{i-1}(v). So δr(v)=di(v)−2di−1(v)\delta_r(v) = d_i(v) - 2 d_{i-1}(v), where δr\delta_r is the distance under rr.

Step 5: reduced distances are below nn. Let PP be a simple shortest path to vv under wi−1w_{i-1}; it has at most n−1n - 1 edges. By Step 1, wi(P)≤2wi−1(P)+(n−1)=2di−1(v)+n−1w_i(P) \le 2 w_{i-1}(P) + (n - 1) = 2 d_{i-1}(v) + n - 1. So di(v)≤2di−1(v)+n−1d_i(v) \le 2 d_{i-1}(v) + n - 1, and by Step 4, 0≤δr(v)≤n−10 \le \delta_r(v) \le n - 1.

Step 6: the sweep is exact. Line L5 is Dijkstra's algorithm with nonnegative integer lengths (Step 3), with the priority queue replaced by buckets swept in increasing order, except that a tentative label of nn or more is not recorded. We show that every reachable vv is scanned from bucket δr(v)\delta_r(v) with label δr(v)\delta_r(v), by induction on δr(v)\delta_r(v) and, for equal values, on the number of edges of a shortest rr-path with fewest edges. For v=sv = s, δr(s)=0\delta_r(s) = 0 and ss starts in bucket 0. For v≠sv \ne s, let uu be the vertex before vv on a shortest rr-path to vv with fewest edges. Then δr(u)=δr(v)−r(u,v)≤δr(v)\delta_r(u) = \delta_r(v) - r(u, v) \le \delta_r(v), and if equal, the path to uu has fewer edges. By induction, uu is scanned from bucket δr(u)\delta_r(u) while the sweep is at level δr(u)≤δr(v)\delta_r(u) \le \delta_r(v), and it offers vv the label δr(u)+r(u,v)=δr(v)≤n−1\delta_r(u) + r(u, v) = \delta_r(v) \le n - 1, which is recorded unless the label is already at most that. Labels are always lengths of paths, so they are never below δr(v)\delta_r(v). So, from that moment on, the label of vv is δr(v)\delta_r(v) and vv is in bucket δr(v)\delta_r(v), which the sweep reaches no earlier than now (the sweep is at level δr(u)≤δr(v)\delta_r(u) \le \delta_r(v)). When the sweep reaches that bucket, vv is scanned with label δr(v)\delta_r(v), unless it was scanned earlier, which would require an earlier label equal to the level then, that is, a label below δr(v)\delta_r(v), impossible. A scanned vertex is not scanned again. So line L5 gives δ(v)=δr(v)\delta(v) = \delta_r(v) for every reachable vv, and the parent of vv is a vertex uu with δr(v)=δr(u)+r(u,v)\delta_r(v) = \delta_r(u) + r(u, v).

Step 7: the update. Line L6 sets d(v)=2di−1(v)+δr(v)=di(v)d(v) = 2 d_{i-1}(v) + \delta_r(v) = d_i(v) by Step 4, for every reachable vv, and leaves ∞\infty for the others. This completes the induction.

Parents. In the last sweep, the parent uu of vv satisfies δr(v)=δr(u)+r(u,v)\delta_r(v) = \delta_r(u) + r(u, v), so by Step 4, db(v)=db(u)+w(u,v)d_b(v) = d_b(u) + w(u, v); such edges, one into each reachable v≠sv \ne s, form a shortest-path tree (each parent was scanned before its child, so there is no cycle). When b=0b = 0, all weights are 0 and the tree of line L1 is a shortest-path tree.

Termination. Line L1 is a finite search, the loop has bb iterations, and each sweep visits nn buckets, each holding finitely many entries. ■\blacksquare

Back to Gabow's scaling algorithm