Proofs: Breaking the sorting barrier for directed SSSP
These are the human proofs of Breaking the sorting barrier for directed SSSP, at full length.
The bounded multi-source recursion computes all distances full
This proof shows: correctness, termination.
Claim. Let every edge weight be a real number . The top call BMSSP of line L12 terminates, and afterwards for every vertex , with exactly when does not reach . This holds for every choice of the parameters and ; the values and matter only for the running time.
Keys. Following the total order of paths in Duan et al. (their Assumption 2.1), compare walks by their key: the length, then the number of edges, then the vertex sequence read from the end, lexicographically. We use three facts.
- (K1) The keys form a total order, and two different walks have different keys.
- (K2) For walks that end at the same vertex , and an edge : if and only if .
- (K3) , because the edge count grows by one and .
Every label is the key of a walk from to , or . Write for the smallest key of a walk from to . It exists: deleting a cycle from a walk does not increase the length and decreases the edge count, so the minimum is over the finitely many simple paths. The walk with key is unique by (K1), and by (K2) its prefix that ends at the previous vertex is . So the paths form a tree, and starts with . A vertex is complete when .
Relaxing forms the candidate , the key of the walk of extended by , and sets when . Labels never increase and never go below . If is complete and is the last edge of , the relaxation makes complete, because then . Conversely, if a relaxation from leaves , then by (K2) is complete and is the vertex before on .
Notation. For a call with bound and frontier , and a key , let be the set of vertices with whose path visits a vertex of . A call is proper if, when it starts,
- (P1) for every , and
- (P2) every incomplete vertex with has a complete vertex of on .
We prove that a proper call terminates and returns with
- (R1) ;
- (R2) every vertex of is in , and every vertex of is complete and in ;
- (R3) , where the labels are taken at the start of the call.
The proof is by induction on the level . First, two facts about any proper call.
Fact A (cover). In a proper call, every has a complete vertex of on . If is incomplete this is (P2). If is complete, let be on . If is complete we are done; otherwise and (P2) gives a complete vertex of on , which is a prefix of .
Fact B (where the relaxations go). Suppose that during a proper call a relaxation from a vertex gives and . Then . Indeed . If was incomplete at the start of the call, (P2) puts a vertex of on . If was complete, then , so is the vertex before on and visits .
Lemma 1 (base case, level 0). A proper call with runs Dijkstra's algorithm from , pushing only candidates below , and stops after vertices are popped. By (P2), is complete: otherwise and (P2) would need a complete vertex of on .
Every popped vertex is complete when it is popped. Suppose is the first popped vertex that is not. Then , and by (P2) visits . Let be the last vertex of that was popped before (there is one, ), and its successor on . When was popped it was complete, and relaxing set and pushed with key , since was not yet popped. That entry stays valid, and , so is popped before unless ; in both cases we get a contradiction. The keys popped are increasing by (K3), and is popped first.
The result. If at most vertices are popped, the heap ran empty, , and is the set of popped vertices. Otherwise is the key of the last popped vertex, and is the popped vertices with smaller keys. In both cases every is popped: if not, take the last popped vertex on and its successor ; as above was pushed with key , so it would have been popped before the last pop. Every popped vertex is complete and lies in by Fact B. So (R1) and (R2) hold. For (R3), by (P1), or is the key of a vertex popped after , so by (K3).
Lemma 2 (FindPivots). In a proper call, after line L3, every is in and complete, or has a complete vertex of on . Also and .
Proof. : by (P1), and every other vertex enters through a relaxation from a vertex of with a candidate below , so Fact B applies.
Let . By Fact A, has a vertex of that is complete at the start; let be the last one, and the rest of . By induction on , after round the vertex is complete and in the next layer: round relaxes from ( is in the first layer, all of ), the candidate is , and it is below .
If FindPivots returns early with , then is complete and on . If , then is complete and in . Otherwise are complete and in .
In the last case, consider the forest on : is an edge when is the stored predecessor of , , and . Each vertex has at most one parent, and keys increase along edges by (K3), so is a forest. The edges are in , since these vertices are complete and .
If is complete and , then , so by (K2), and . So every ancestor in of a complete vertex is complete and lies on its path. Let be the root of the tree of . Then is complete and on , a prefix of .
We claim . If not, entered when a relaxation during FindPivots set its label. At the last such time, its label became with the new predecessor. If later dropped, then , which is impossible. So and is not a root.
So is a root in whose tree has at least vertices, hence .
Lemma 3 (the loop). Consider a proper call at level , and let done be the union of the sets returned so far. Call done pending. Before every iteration, and when the loop stops:
- (J0) every vertex in done is complete and in ; every value in is below , and it is at least of the last subcall, if there was one;
- (J) every pending satisfies one of the following:
- (a) and is complete;
- (b) contains a vertex of done; for the last such vertex, its successor on is complete and is a key of with value ;
- (c) contains no vertex of done, and some complete vertex on is a key of with value .
Also, every key of lies in .
Start. done is empty, and holds the pivots with their labels. By Lemma 2 each pending satisfies (a) or (c). Pivots are in .
Values. keeps the smaller value when a key is inserted again. A key with value keeps that value until it is pulled, since no candidate is below .
The subcall is proper. Line L6 pulls the keys with values below ; values are keys of different vertices, so they are distinct. If is left empty, . The vertices of done are then removed from .
- (P1) holds because is at most the value of in , which is below .
- For (P2), let be incomplete with . By (P2) of this call and Fact A, . It is not in done, because those vertices are complete, and it is not in case (a). In case (b) or (c), the vertex or has value at most , so it was pulled. It is not in done, so it is in , and it is complete and on .
If ends up empty, no subcall happens, and the iteration only removes keys of done vertices; such keys are never the or of (J). So (J0) and (J) still hold.
After the subcall. By induction, the subcall returns with (R1) to (R3) for . Every vertex of is a key of , so it lies in . Hence every vertex of is complete, and its path visits and so , which keeps done inside . Relaxations from in line L8 insert or prepend only candidates with ; by Fact B these vertices lie in . All other keys have values at least . So (J0) holds.
(J) after the iteration. Let be pending afterwards. Case (a) persists, so assume is not in case (a).
- If meets done, let be the last vertex of in done and its successor; is complete, because and the edge was relaxed after became complete.
- If , line L8 relaxed and the candidate is . If , then (as visits ), which contradicts the choice of . So , and line L9 or line L10 put into with value .
- If was in done before, then (J) before the iteration gave as a key with value . If was pulled now, it is in and not in . Then , because otherwise . So line L10 prepends it again with value .
- If does not meet done, then before the iteration it was in case (c) with some . If was pulled, , so as above , and line L10 puts it back with value .
Termination of the loop. Take a subcall. Let have the smallest label at the start of the subcall. By (R3), , so . Since is not in done, done grows by at least one vertex. So there are at most subcalls, and between two of them each iteration removes keys without adding any. Every iteration pulls at least one key, so the loop stops.
Lemma 4 (the result of the call). A proper call at level satisfies (R1) to (R3).
(R1) holds by line L11. For (R2), let , and suppose is pending. Cases (b) and (c) give a key with value at most . But when the loop stops, either is empty, or every value is at least of the last subcall, which is at least , by (J0). So is in case (a): , complete, with , and line L11 adds it to . Every vertex added to is in done, which is complete and in by (J0), or is a vertex of with . Such a vertex lies in by Lemma 2, so it is in done or in case (a), and in both cases it is complete.
For (R3): if there was no subcall, for every by (P1). Otherwise for the last subcall. is larger than every label in . By (R3) of the subcall, for some . By Fact A, has a vertex that is complete at the start, and , because does not decrease along . (lemma)
The top call. With , and the call is proper: is complete, and every reachable has on . Its level gives , so the loop stops only when is empty. Then (J) leaves only case (a): every reachable vertex is in done or in , and complete. So , whose first entry is . A vertex that does not reach is never the target of a relaxation from a finite label, so it keeps . The recursion depth is , every FindPivots is rounds, every base case pops each vertex at most once, and every loop stops by Lemma 3, so the algorithm terminates.
The stored keys. The implementation stores only the first four entries of a key: (length, edge count, , predecessor). Labels of different vertices differ in the third entry. Two candidates for the same vertex with the same four entries come from the same predecessor , with the same length and edge count for . For these, the code compares with and keeps the newer one. Its full key is never larger, because the label of only decreases. So every comparison of stored labels agrees with the comparison of full keys, except between two such candidates; they have equal lengths, so the distances are not affected.