python----並查集
阿新 • • 發佈:2017-10-28
root urn weight end .cn clas 性能 connected find
Quick Find
# -*- coding: utf-8 -*- class QuickFind(object): id = [] cnt = 0 # the number of the sets def __init__(self, n): self.cnt = n for i in range(0, n): self.id.append(i) def connected(self, p, q): return self.find(p) == self.find(q) deffind(self,p): return self.id[p] def union(self,p,q): id_p = self.find(p) if not self.connected(p,q): for i in range(0,len(self.id)): if self.id[i] == id_p: self.id[i] = self.id[q] #combine self.cnt -= 1 qf = QuickFind(10)print("initial id list is %s" % (‘,‘).join(str(x) for x in qf.id)) list = [ (4,3), (3,8), (6,5), (9,4), (2,1), (8,9), (5,0), (7,2), (6,1), (1,0), (6,7) ] for edge in list : p = edge[0] q = edge[1] qf.union(p,q)print("%d and %d is connected? %s"%(p,q,str(qf.connected(p,q)))) print("final id list is %s" %(",").join(str(x) for x in qf.id)) print("count of sets is : %d" % qf.cnt)
connect更新的時候需要遍歷,可以借用樹結構來減小時間復雜度。
# -*- coding: utf-8 -*- class QuickUnion(object): id = [] cnt = 0 # the number of the sets def __init__(self, n): self.cnt = n for i in range(0, n): self.id.append(i) def connected(self, p, q): return self.find(p) == self.find(q) def find(self,x): while(x != self.id[x]): x = self.id[x] return x def union(self,p,q): root_p = self.find(p) root_q = self.find(q) if not self.connected(p,q): self.id[root_p] = root_q self.cnt -= 1 qu = QuickUnion(10) print("initial id list is %s" % (‘,‘).join(str(x) for x in qf.id)) list = [ (4,3), (3,8), (6,5), (9,4), (2,1), (8,9), (5,0), (7,2), (6,1), (1,0), (6,7) ] for edge in list : p = edge[0] q = edge[1] qu.union(p,q) print("%d and %d is connected? %s"%(p,q,str(qu.connected(p,q)))) print("final id list is %s" %(",").join(str(x) for x in qu.id)) print("count of sets is : %d" % qu.cnt)
Weighted Quick Union
Quick Union 可能會退化成鏈,導致性能下降,可以通過Weighted Quick Union盡量平衡樹的高度,從而提升性能。
# -*- coding: utf-8 -*- class WeightedQuickUnion(object): id = [] cnt = 0 # the number of the sets sz = [] def __init__(self, n): self.cnt = n for i in range(0, n): self.id.append(i) self.sz.append(1) def connected(self, p, q): return self.find(p) == self.find(q) def find(self,x): while(x != self.id[x]): x = self.id[x] return x def union(self,p,q): root_p = self.find(p) root_q = self.find(q) if not self.connected(p,q): if self.sz[q] > self.sz[p]: #保證小樹連大樹,若大樹連小樹可能退化成鏈 self.id[root_p] = root_q self.cnt -= 1 self.sz[q] += self.sz[p] else : self.id[root_q] = root_p self.cnt -= 1 self.sz[p] += self.sz[q] wqu = WeightedQuickUnion(10) print("initial id list is %s" % (‘,‘).join(str(x) for x in wqu.id)) list = [ (4,3), (3,8), (6,5), (9,4), (2,1), (8,9), (5,0), (7,2), (6,1), (1,0), (6,7) ] for edge in list : p = edge[0] q = edge[1] wqu.union(p,q) print("%d and %d is connected? %s"%(p,q,str(wqu.connected(p,q)))) print("final id list is %s" %(",").join(str(x) for x in wqu.id)) print("count of components is : %d" % wqu.cnt)
可通過壓縮查找進一步提升性能,類似樹樁。
參考:http://www.cnblogs.com/learnbydoing/p/6896472.html?utm_source=itdadao&utm_medium=referral
python----並查集