Algorithm Search⌘K

Proofs: Skyline sweep

These are the human proofs of Skyline sweep, at full length.

The skyline sweep outputs the shortest list of key points of the skyline full

This proof shows: correctness, termination.

Setting. The input is n≥0n \ge 0 buildings (Li,Ri,Hi)(L_i, R_i, H_i) with Li<RiL_i < R_i and Hi>0H_i > 0. Building ii is active at xx when Li≤x<RiL_i \le x < R_i. Let f(x)=max⁡{Hi:i active at x}f(x) = \max\{H_i : i \text{ active at } x\}, and f(x)=0f(x) = 0 when no building is active. Let X=[x1<x2<⋯<xk]X = [x_1 < x_2 < \cdots < x_k] be the distinct values of all LiL_i and RiR_i, as built in line L1. We write xk+1=+∞x_{k+1} = +\infty.

Lemma 1 (ff is a step function on the events). For 1≤t≤k1 \le t \le k, ff is constant on [xt,xt+1)[x_t, x_{t+1}). Also f(x)=0f(x) = 0 for x<x1x < x_1 and for x≥xkx \ge x_k.

Proof. Take x,y∈[xt,xt+1)x, y \in [x_t, x_{t+1}) with x<yx < y. If building ii is active at xx but not at yy, then Ri≤yR_i \le y and Ri>xR_i > x, so Ri∈(x,y]⊆(xt,xt+1)R_i \in (x, y] \subseteq (x_t, x_{t+1}), which contains no value of XX. If ii is active at yy but not at xx, then Li∈(x,y]L_i \in (x, y], the same contradiction. So the same buildings are active at xx and at yy, and f(x)=f(y)f(x) = f(y). For x<x1x < x_1, each Li≥x1>xL_i \ge x_1 > x, so no building is active. For x≥xkx \ge x_k, each Ri≤xk≤xR_i \le x_k \le x, so no building is active. □\square

Lemma 2 (heap invariant). Line L2 sorts BB by LL. For 1≤t≤k1 \le t \le k, after line L8 in the iteration for x=xtx = x_t:

(a) The entries inserted so far are exactly the buildings with Li≤xtL_i \le x_t, and i−1i - 1 is their number. (b) Each building that is active at xtx_t has its entry in QQ. (c) If QQ is not empty, its top entry belongs to a building that is active at xtx_t.

Proof. Part (a), by induction on tt. Before the first iteration no entry was inserted and i=1i = 1. Assume that before the iteration for xtx_t the inserted entries are those with Li≤xt−1L_i \le x_{t-1} (none when t=1t = 1). Since BB is sorted by LL and each LL is a value of XX, the next buildings in BB have L≥xtL \ge x_t, and those with L=xtL = x_t come first. The loop of line L5 inserts exactly them and stops at the first building with L>xtL > x_t or at i=n+1i = n + 1. No LiL_i lies strictly between xt−1x_{t-1} and xtx_t, so the inserted entries are now those with Li≤xtL_i \le x_t.

Part (b). Let building jj be active at xtx_t. By (a) its entry was inserted. An entry is removed only by line L8 in some iteration s≤ts \le t, and only when its R≤xs≤xtR \le x_s \le x_t. But Rj>xtR_j > x_t, so the entry of jj was never removed.

Part (c). The loop of line L7 stops only when QQ is empty or the top entry has R>xtR > x_t. The top entry was inserted, so by (a) its L≤xtL \le x_t. With R>xtR > x_t its building is active at xtx_t. □\square

Lemma 3 (the height). After line L9 in the iteration for xtx_t, h=f(xt)h = f(x_t).

Proof. If QQ is empty, then by Lemma 2(b) no building is active at xtx_t, so f(xt)=0=hf(x_t) = 0 = h. Otherwise let (H,R)(H, R) be the top entry, so HH is the largest height in QQ. By Lemma 2(c), HH is the height of an active building, so H≤f(xt)H \le f(x_t). By Lemma 2(b), each active building has its entry in QQ, so each active height is at most HH, and f(xt)≤Hf(x_t) \le H. So h=H=f(xt)h = H = f(x_t). □\square

Theorem. SKYLINE-SWEEP terminates and returns the list P=[(xt,f(xt)):1≤t≤k, f(xt)≠f(xt−1)]P = [(x_t, f(x_t)) : 1 \le t \le k,\ f(x_t) \ne f(x_{t-1})], where f(x0)=0f(x_0) = 0 by convention. This list is the unique shortest list of key points: its xx values increase, consecutive heights differ, f(x)=hjf(x) = h_j on [xj,xj+1)[x_j, x_{j+1}) for consecutive points (xj,hj)(x_j, h_j), (xj+1,hj+1)(x_{j+1}, h_{j+1}) of PP, and f(x)=0f(x) = 0 before the first point and from the last point on.

Proof. Termination. The loop of line L4 runs k≤2nk \le 2n times. Each run of line L6 increases ii by 1 and i≤n+1i \le n + 1, so line L6 runs at most nn times in total. Each run of line L8 removes one of the at most nn inserted entries, so line L8 runs at most nn times in total. So the algorithm stops.

The output. We show by induction on tt that after the iteration for xtx_t, prev=f(xt)prev = f(x_t) and outout is the part of PP with x≤xtx \le x_t. Before the first iteration prev=0=f(x0)prev = 0 = f(x_0) and outout is empty. In the iteration for xtx_t, Lemma 3 gives h=f(xt)h = f(x_t), and by the hypothesis prev=f(xt−1)prev = f(x_{t-1}). Lines L10 and L11 append (xt,f(xt))(x_t, f(x_t)) exactly when f(xt)≠f(xt−1)f(x_t) \ne f(x_{t-1}), and then set prev=f(xt)prev = f(x_t). If f(xt)=f(xt−1)f(x_t) = f(x_{t-1}), then prevprev already equals f(xt)f(x_t). At the end, out=Pout = P.

PP describes ff. By Lemma 1, ff is constant on each [xt,xt+1)[x_t, x_{t+1}), and between two consecutive points of PP the value ff does not change at the events in between, because those events are not in PP. So f=hjf = h_j on [xj,xj+1)[x_j, x_{j+1}). Before the first point of PP, ff is 0 on (−∞,x1)(-\infty, x_1) by Lemma 1 and does not change at the events before the first point. After the last point (xj,hj)(x_j, h_j) of PP, ff does not change, and f(xk)=0f(x_k) = 0 by Lemma 1, so hj=0h_j = 0 and f=0f = 0 from xjx_j on. Consecutive heights in PP differ because each point of PP has a height different from the value of ff just before it, which is the height of the previous point.

PP is the shortest list. Let P′P' be any list of key points that describes ff in this way. At each xtx_t with f(xt)≠f(xt−1)f(x_t) \ne f(x_{t-1}), ff changes value at xtx_t: it is f(xt−1)f(x_{t-1}) on [xt−1,xt)[x_{t-1}, x_t) and f(xt)f(x_t) at xtx_t. A list that describes ff by values on half-open pieces must start a new piece at each point where ff changes, so P′P' has a point at xtx_t. So P′P' contains a point at each xx of PP, and ∣P′∣≥∣P∣|P'| \ge |P|. If also consecutive heights of P′P' differ, P′P' has no point where ff does not change, so P′=PP' = P. ■\blacksquare

Cost of the heap operations. The termination argument also gives the cost: at most nn INSERT and at most nn EXTRACT-MAX calls in total, each on a heap of at most nn entries, so O(nlog⁡n)O(n \log n) time for the heap, plus O(nlog⁡n)O(n \log n) for the sorts of lines L1 and L2.

Back to Skyline sweep