Algorithm Search⌘K

Proofs: Weighted union-find

These are the human proofs of Weighted union-find, at full length.

Weighted union-find keeps potentials that satisfy exactly the implied facts full

This proof shows: correctness, termination.

Fix an abelian group (G,+,0)(G, +, 0). Let FF be the set of facts val(x)−val(y)=d\mathrm{val}(x) - \mathrm{val}(y) = d accepted so far, that is, added by a union that returned true. Say that FF implies val(x)−val(y)=e\mathrm{val}(x) - \mathrm{val}(y) = e when every assignment val:E→G\mathrm{val} : E \to G that satisfies all facts of FF also satisfies this one. For each element xx with root rr, pot(x)\mathrm{pot}(x) is the sum of ww along the path from xx to rr, excluding rr, and pot(r)=0\mathrm{pot}(r) = 0.

We prove that after each operation:

(T) The parent pointers form a forest with union by size, as in the disjoint-set forest, and r.w=0r.w = 0 at each root rr.

(P) Each fact of FF relates two elements of one tree and is satisfied by pot\mathrm{pot}.

(I) For xx and yy in one tree, FF implies val(x)−val(y)=pot(x)−pot(y)\mathrm{val}(x) - \mathrm{val}(y) = \mathrm{pot}(x) - \mathrm{pot}(y). For xx and yy in different trees, FF implies no fact about val(x)−val(y)\mathrm{val}(x) - \mathrm{val}(y).

The forest part of (T) is proved on the disjoint-set forest page, because the parent pointers and sizes change exactly as there; the values do not affect them. In particular every find stops.

Initialization and MAKE-SET. A new element is a root with w=0w = 0 and no facts. Each tree of one element satisfies (P) and (I) trivially, and pot\mathrm{pot} of every other element is unchanged.

Lemma 1 (FIND). FIND(x)(x) changes no potential, keeps (T), (P) and (I), and afterwards x.w=pot(x)x.w = \mathrm{pot}(x) if xx is not a root.

Proof. By induction on the depth kk of xx. If k=0k = 0, line L3 returns, nothing changes, and xx is the root. Let k≥1k \ge 1, with parent q=x.pq = x.p. By the induction hypothesis, FIND(q)(q) changes no potential and leaves q.w=pot(q)q.w = \mathrm{pot}(q) if qq is not a root; if qq is the root, q.w=0=pot(q)q.w = 0 = \mathrm{pot}(q) by (T). So before line L5, pot(x)=x.w+pot(q)=x.w+q.w\mathrm{pot}(x) = x.w + \mathrm{pot}(q) = x.w + q.w, because xx still points to qq. Line L5 sets x.wx.w to this value and line L6 points xx to the root, so the new potential of xx is $x.w + 0 = $ the old pot(x)\mathrm{pot}(x). The nodes of the subtree of xx reach the root through xx, and their sums up to xx do not change, so their potentials do not change either. No tree changes its node set, FF does not change, so (P) and (I) still hold. The Python form computes the same values with two loops: it collects the path, and from the node nearest the root down, it sets each value to its own value plus the new value of its parent, which is the parent's potential. □\square

DIFF(x,y)(x, y). By Lemma 1, after line L8 both finds leave x.w=pot(x)x.w = \mathrm{pot}(x) and y.w=pot(y)y.w = \mathrm{pot}(y) (a root has w=0=potw = 0 = \mathrm{pot}). If the roots differ, (I) says FF fixes no difference, and NONE is right. Otherwise line L9 returns pot(x)−pot(y)\mathrm{pot}(x) - \mathrm{pot}(y), which by (I) is the difference that FF implies.

UNION(x,y,d)(x, y, d), same tree. After line L10, x.w=pot(x)x.w = \mathrm{pot}(x) and y.w=pot(y)y.w = \mathrm{pot}(y). Let e=pot(x)−pot(y)e = \mathrm{pot}(x) - \mathrm{pot}(y). By (I), FF implies val(x)−val(y)=e\mathrm{val}(x) - \mathrm{val}(y) = e, and by (P) pot\mathrm{pot} satisfies FF. If d=ed = e, the new fact is implied by FF; adding it changes no set of solutions, and pot\mathrm{pot} satisfies it, so (P) and (I) hold. If d≠ed \ne e, the new fact contradicts FF, because every solution of FF has the difference ee, and pot\mathrm{pot} is a solution. Line L11 returns false and the fact is not added. Either way the answer is right.

UNION(x,y,d)(x, y, d), different trees. The fact val(x)−val(y)=d\mathrm{val}(x) - \mathrm{val}(y) = d is the same as val(y)−val(x)=−d\mathrm{val}(y) - \mathrm{val}(x) = -d, so after the swap of line L12 we may assume that xx is in the tree XX with root rxrx and yy in the tree YY with root ryry, with ∣X∣≤∣Y∣|X| \le |Y|. Write pot\mathrm{pot} for the potentials before line L13 and pot′\mathrm{pot}' after.

Potentials after the link. Line L13 sets rx.p=ryrx.p = ry and rx.w=crx.w = c, where c=d+pot(y)−pot(x)c = d + \mathrm{pot}(y) - \mathrm{pot}(x). For z∈Xz \in X, the path from zz now goes to rxrx and then to ryry, so pot′(z)=pot(z)+c\mathrm{pot}'(z) = \mathrm{pot}(z) + c. For z∈Yz \in Y and for the other trees, nothing changes. The root ryry keeps w=0w = 0, so (T) holds.

(P). Old facts relate two elements of one old tree. Inside XX all potentials shift by the same cc, so differences are kept; the others do not change. For the new fact, pot′(x)−pot′(y)=pot(x)+c−pot(y)=d\mathrm{pot}'(x) - \mathrm{pot}'(y) = \mathrm{pot}(x) + c - \mathrm{pot}(y) = d.

(I), the new tree. Let F′=F∪{val(x)−val(y)=d}F' = F \cup \{\mathrm{val}(x) - \mathrm{val}(y) = d\}. Take u,v∈X∪Yu, v \in X \cup Y. If both are in XX, then FF implies val(u)−val(v)=pot(u)−pot(v)=pot′(u)−pot′(v)\mathrm{val}(u) - \mathrm{val}(v) = \mathrm{pot}(u) - \mathrm{pot}(v) = \mathrm{pot}'(u) - \mathrm{pot}'(v), and so does F′⊇FF' \supseteq F; the same holds in YY. If u∈Xu \in X and v∈Yv \in Y, then every solution of F′F' has

val(u)−val(v)=(val(u)−val(x))+(val(x)−val(y))+(val(y)−val(v))=(pot(u)−pot(x))+d+(pot(y)−pot(v)),\mathrm{val}(u) - \mathrm{val}(v) = (\mathrm{val}(u) - \mathrm{val}(x)) + (\mathrm{val}(x) - \mathrm{val}(y)) + (\mathrm{val}(y) - \mathrm{val}(v)) = (\mathrm{pot}(u) - \mathrm{pot}(x)) + d + (\mathrm{pot}(y) - \mathrm{pot}(v)),

which equals pot(u)+c−pot(v)=pot′(u)−pot′(v)\mathrm{pot}(u) + c - \mathrm{pot}(v) = \mathrm{pot}'(u) - \mathrm{pot}'(v).

(I), different trees. Let uu and vv be in different trees after the union. We show that F′F' fixes no value of val(u)−val(v)\mathrm{val}(u) - \mathrm{val}(v). Let the tree of uu be UU. For each g∈Gg \in G, define valg(z)=pot′(z)+g\mathrm{val}_g(z) = \mathrm{pot}'(z) + g for z∈Uz \in U and valg(z)=pot′(z)\mathrm{val}_g(z) = \mathrm{pot}'(z) otherwise. Each fact of F′F' relates two elements of one tree, by (P), so it is satisfied by valg\mathrm{val}_g, which shifts each tree by a constant. Then valg(u)−valg(v)=pot′(u)−pot′(v)+g\mathrm{val}_g(u) - \mathrm{val}_g(v) = \mathrm{pot}'(u) - \mathrm{pot}'(v) + g takes every value of GG as gg varies. So no fact about this difference is implied. The same argument, applied before the union, shows that the new fact relating XX and YY never contradicts FF, so returning true is right.

Line L14 updates the size of the new root, which is part of (T).

Conclusion. By induction on the operations, (T), (P) and (I) hold after each operation. So each union returns false exactly when its fact contradicts the accepted facts, and each DIFF returns the difference that the facts imply, or NONE when they imply none. ■\blacksquare

Back to Weighted union-find