2
Union-find data structure.
4
# Copyright (C) 2004-2011 by
5
# Aric Hagberg <hagberg@lanl.gov>
6
# Dan Schult <dschult@colgate.edu>
7
# Pieter Swart <swart@lanl.gov>
13
"""Union-find data structure.
15
Each unionFind instance X maintains a family of disjoint sets of
16
hashable objects, supporting the following two methods:
18
- X[item] returns a name for the set containing the given item.
19
Each set is named by an arbitrarily-chosen one of its members; as
20
long as the set remains unchanged it will keep the same name. If
21
the item is not yet part of a set in X, a new singleton set is
24
- X.union(item1, item2, ...) merges the sets containing each item
25
into a single larger set. If any item is not yet part of a set
26
in X, it is added to X as one of the members of the merged set.
28
Union-find data structure. Based on Josiah Carlson's code,
29
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/215912
30
with significant additional changes by D. Eppstein.
31
http://www.ics.uci.edu/~eppstein/PADS/UnionFind.py
36
"""Create a new empty union-find structure."""
40
def __getitem__(self, object):
41
"""Find and return the name of the set containing the object."""
43
# check for previously unknown object
44
if object not in self.parents:
45
self.parents[object] = object
46
self.weights[object] = 1
49
# find path of objects leading to the root
51
root = self.parents[object]
52
while root != path[-1]:
54
root = self.parents[root]
56
# compress the path and return
58
self.parents[ancestor] = root
62
"""Iterate through all items ever found or unioned by this structure."""
63
return iter(self.parents)
65
def union(self, *objects):
66
"""Find the sets containing the objects and merge them all."""
67
roots = [self[x] for x in objects]
68
heaviest = max([(self.weights[r],r) for r in roots])[1]
71
self.weights[heaviest] += self.weights[r]
72
self.parents[r] = heaviest