Proofs: Dial's algorithm
These are the human proofs of Dial's algorithm, at full length.
Dial's algorithm computes the distances full
This proof shows: correctness, termination.
Claim. Let be a directed graph with integer weights in and a source . DIAL ends, and at the end for every ; for every with , .
Notation. An entry is an occurrence of a vertex in a bucket; its key is the label the vertex got when the entry was added. Let be the multiset of keys of all entries in the buckets; .
Step 1: the window. Invariant: every key in lies in , and an entry with key is in bucket .
It holds after line L3, with and . Line L10 adds the key with , inside the window, to the right bucket. Lines L6 and L7 only remove entries. Line L5 raises by one only when is empty. The values have distinct residues modulo , so only key maps to that bucket; its being empty means , and all keys lie in .
Step 2: termination. In line L5, , so some key exists, and stops at the latest at . So line L5 ends. Each label drop in line L10 lowers ; while is scanned, , and a vertex is scanned only when (line L7), and never decreases, so each vertex is scanned at most once (a second scan would need the same label at a later moment, but its entry with that key was removed and labels only fall). So line L10 runs at most times, there are at most entries in total, each pass of line L4 removes one, and the loop ends.
Step 3: the same run as Dijkstra. By Step 1, the bucket emptied in line L6 holds exactly the entries with key , and all keys are at least . So line L6 removes an entry of least key, as extract-min does on a binary heap holding the same entries. The key of an entry for satisfies key, since labels only fall; line L7 skips it exactly when $d[u] < $ key , which is the stale test of lazy-deletion Dijkstra. Lines L8 to L10 relax the edges out of with . So the sequence of scanned vertices and label changes is that of Dijkstra's algorithm with a lazy-deletion priority queue, with ties among equal keys broken by the order inside a bucket.
Step 4: correctness. Dijkstra's algorithm with lazy deletion, with any tie-breaking, ends with and a shortest-path tree in when all weights are nonnegative; see the proof on the correctness of Dijkstra's algorithm. For completeness, the core of it in this setting: when is scanned at index , suppose , and let be a shortest path to . Its first vertex not yet scanned has a scanned predecessor (or is ), and the relaxation of when was scanned gave by induction on scan order. So an entry with key at most is in the buckets, against Step 1. Hence when scanned. Unscanned vertices at the end have no entry; a reachable vertex gets an entry when its predecessor on a shortest path is scanned, so every reachable vertex is scanned, and an unreachable vertex keeps , since every finite label is the weight of a walk from . When was last set, it was with already final, which gives the tree equation.