【问题标题】:Disjoint set implementation in PythonPython中的不相交集实现
【发布时间】:2019-05-31 02:01:16
【问题描述】:

我对 Python 比较陌生。我正在研究不相交集,并按如下方式实现:

class DisjointSet:
    def __init__(self, vertices, parent):
        self.vertices = vertices
        self.parent = parent

    def find(self, item):
        if self.parent[item] == item:
            return item
        else:
            return self.find(self.parent[item])

    def union(self, set1, set2):
        self.parent[set1] = set2

现在在驱动代码中:

def main():
    vertices = ['a', 'b', 'c', 'd', 'e', 'h', 'i']
    parent = {}

    for v in vertices:
        parent[v] = v

    ds = DisjointSet(vertices, parent)
    print("Print all vertices in genesis: ")
    ds.union('b', 'd')

    ds.union('h', 'b')
    print(ds.find('h')) # prints d (OK)
    ds.union('h', 'i')
    print(ds.find('i')) # prints i (expecting d)

main()

所以,起初我将所有节点初始化为单独的不相交集。然后联合bdhb 组成集合:hbd 然后合并hi,这应该(如我所料)给我们集合:ihbd。我知道由于在union(set1, set2) 的这一行中设置了父级:

self.parent[set1] = set2

我将h 的父级设置为i,从而将其从bd 的集合中删除。如何实现一组ihbd,其中union() 中的参数顺序不会产生不同的结果?

【问题讨论】:

标签: python-3.x algorithm data-structures disjoint-sets


【解决方案1】:

您的程序无法正常运行,因为您误解了不相交集实现的算法。联合是通过修改 root 节点的父节点而不是作为输入提供的节点来实现的。正如您已经注意到的,盲目地修改您在输入中收到的任何节点的父节点只会破坏以前的联合。

这是一个正确的实现:

def union(self, set1, set2):
    root1 = self.find(set1)
    root2 = self.find(set2)
    self.parent[root1] = root2

我还建议阅读Disjoint-set data structure 了解更多信息以及可能的优化。

【讨论】:

    【解决方案2】:

    为了使您的实施更快,您可能希望更新父级 find()

        def find(self, item):
            if self.parent[item] == item:
                return item
            else:
                res = self.find(self.parent[item])
                self.parent[item] = res
                return res
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-03-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-28
      • 2015-10-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多