Algorithm Search⌘K

Proofs: Highway hierarchies

These are the human proofs of Highway hierarchies, at full length.

The two-level highway query returns shortest paths full

This proof shows: correctness, termination.

Claim. Let all weights be nonnegative, let H≥1H \ge 1, and let radii and highway edges be as in lines L1 and L2. For all s,ts, t, the query returns dist⁡(s,t)\operatorname{dist}(s, t), and when it is finite, a walk of that weight (a simple path when all weights are positive).

If s=ts = t the query returns 0 and [s][s], which is correct. Assume s≠ts \ne t.

Step 1: neighborhoods are closed along shortest paths. If v∈N→(s)v \in N^\to(s) and xx is a vertex on a shortest ss-vv path, then dist⁡(s,x)≤dist⁡(s,v)≤r→(s)\operatorname{dist}(s, x) \le \operatorname{dist}(s, v) \le r^\to(s) (weights are nonnegative), so x∈N→(s)x \in N^\to(s). Symmetrically, if u∈N←(t)u \in N^\gets(t) and xx is on a shortest uu-tt path, then x∈N←(t)x \in N^\gets(t).

Step 2: each side is Dijkstra on a fixed graph. Let FF be the graph with all edges out of vertices of N→(s)N^\to(s) plus all highway edges. We claim the forward side runs Dijkstra's algorithm on FF from ss. It is a Dijkstra search, so when it scans uu, its label d→[u]d^\to[u] is at least dist⁡(s,u)\operatorname{dist}(s, u) (every label is the weight of a real path). If u∉N→(s)u \notin N^\to(s), then d→[u]≥dist⁡(s,u)>r→(s)d^\to[u] \ge \operatorname{dist}(s, u) > r^\to(s), so line L4 allows only highway edges at uu, the edges of FF. If u∈N→(s)u \in N^\to(s), a shortest ss-uu path lies in N→(s)N^\to(s) by Step 1, all of whose out-edges are allowed; by induction over the scan order, as in the correctness of Dijkstra, d→[u]=dist⁡(s,u)≤r→(s)d^\to[u] = \operatorname{dist}(s, u) \le r^\to(s) when uu is scanned, so all its edges are allowed, again the edges of FF. (The induction: the vertices of N→(s)N^\to(s) are scanned in order of their distance, and each is relaxed from its predecessor on a shortest path, which is in N→(s)N^\to(s) and was scanned with its true distance.) So the forward side is Dijkstra on FF. In the same way, the backward side is Dijkstra from tt on the reverse of BB, the graph of all edges into vertices of N←(t)N^\gets(t) plus all highway edges.

Step 3: a shortest path splits. Suppose dist⁡(s,t)<∞\operatorname{dist}(s, t) < \infty and let P=(p0=s,…,pk=t)P = (p_0 = s, \ldots, p_k = t) be a shortest path. Let jj be the least index with pj∈N←(t)p_j \in N^\gets(t); it exists since t∈N←(t)t \in N^\gets(t). By Step 1, pj,…,pkp_j, \ldots, p_k are all in N←(t)N^\gets(t), so the edges of PP after pjp_j end in N←(t)N^\gets(t) and lie in BB. Consider an edge (pi,pi+1)(p_i, p_{i+1}) with i<ji < j. If pi∈N→(s)p_i \in N^\to(s), the edge is in FF. Otherwise pi+1∉N→(s)p_{i+1} \notin N^\to(s) by Step 1 (applied to the prefix of PP up to pi+1p_{i+1}, a shortest path), and pi∉N←(t)p_i \notin N^\gets(t) since i<ji < j; as (pi,pi+1)(p_i, p_{i+1}) is on the shortest ss-tt path PP, it is a highway edge by line L2, so it is in FF. Hence the prefix of PP up to pjp_j is in FF, and the suffix from pjp_j is in BB, so dist⁡F(s,pj)+dist⁡B(pj,t)≤w(P)=dist⁡(s,t)\operatorname{dist}_F(s, p_j) + \operatorname{dist}_B(p_j, t) \le w(P) = \operatorname{dist}(s, t).

Step 4: the query. Every value given to μ\mu is a label of one side plus a label of the other at the same vertex, the weight of an ss-tt walk in GG, so μ≥dist⁡(s,t)\mu \ge \operatorname{dist}(s, t) always. If dist⁡(s,t)=∞\operatorname{dist}(s, t) = \infty there is no such walk, no meeting vertex is recorded, and the query returns ∞\infty. Otherwise let z=pjz = p_j from Step 3. Suppose the query stops with μ>dist⁡(s,t)\mu > \operatorname{dist}(s, t). Then both least keys were at least μ>dist⁡F(s,z)\mu > \operatorname{dist}_F(s, z) and >dist⁡B(z,t)> \operatorname{dist}_B(z, t), so both Dijkstra searches had scanned zz with labels dist⁡F(s,z)\operatorname{dist}_F(s, z) and dist⁡B(z,t)\operatorname{dist}_B(z, t) (Step 2). At the later of the two scans, line L5 set μ≤dist⁡F(s,z)+dist⁡B(z,t)≤dist⁡(s,t)\mu \le \operatorname{dist}_F(s, z) + \operatorname{dist}_B(z, t) \le \operatorname{dist}(s, t), and μ\mu never increases, a contradiction. So μ=dist⁡(s,t)\mu = \operatorname{dist}(s, t). Following the predecessors of the remembered vertex on both sides gives an ss-tt walk of weight at most the value of μ\mu when it was set (labels only fall), hence exactly dist⁡(s,t)\operatorname{dist}(s, t). (The two chains are each simple, coming from Dijkstra trees; if they share a vertex other than the meeting vertex, the result is a walk of that weight, which with positive weights cannot happen.)

Termination. Each side scans each vertex at most once and pushes one heap entry per relaxation, so the loop ends. ■\blacksquare

Back to Highway hierarchies