【发布时间】:2013-11-22 20:58:34
【问题描述】:
所以这就是我想要做的:我有一个包含几个等价关系的列表:
l = [[1, 2], [2, 3], [4, 5], [6, 7], [1, 7]]
我想合并共享一个元素的集合。这是一个示例实现:
def union(lis):
lis = [set(e) for e in lis]
res = []
while True:
for i in range(len(lis)):
a = lis[i]
if res == []:
res.append(a)
else:
pointer = 0
while pointer < len(res):
if a & res[pointer] != set([]) :
res[pointer] = res[pointer].union(a)
break
pointer +=1
if pointer == len(res):
res.append(a)
if res == lis:
break
lis,res = res,[]
return res
然后打印出来
[set([1, 2, 3, 6, 7]), set([4, 5])]
这是正确的,但是当等价关系太大时太慢了。我查了关于联合查找算法的描述:http://en.wikipedia.org/wiki/Disjoint-set_data_structure 但我仍然在编写 Python 实现时遇到问题。
【问题讨论】:
-
我不确定您是否需要自己实现或可以使用现有模块,但在后一种情况下 NetworkX has an implementation of Union-Find 对我来说效果很好。
-
请参阅this question 了解许多实现和一些时序测试。 [这通常称为“集合合并”。]
-
看看我的 O(n) 时间复杂度解决方案。所有其他解决方案都给出 O(n^2)。你的清单可以有多大?我已经测试了一大组 100,000 个 2 元组,它在不到一秒的时间内运行(0.5 秒到 0.8 秒)。
-
当你只做联合时,你不需要联合查找。一个简单的洪水填充效果很好,速度更快。
标签: python list union-find