【问题标题】:Improving Implementation of Finding a Minimum Spanning Tree改进寻找最小生成树的实现
【发布时间】:2015-10-27 00:49:12
【问题描述】:

我正在尝试实现 Kruskal 算法以在 Python 中找到最小生成树来解决在线法官的问题,但我遇到了时间限制问题。该问题以递增顺序给出了一系列边,并询问最小生成树是否可能。完整问题规范可见here.

这是我的问题代码:

import sys
raw_input = sys.stdin.readline
line = map(int, raw_input().split())
n = line[0]
m = line[1]
dict1 = {}
lists = []

for i in xrange(1, n + 1):
    dict1[i] = set([i])

for i in xrange(m):
    edge = map(int, raw_input().split())
    a = edge[0]
    b = edge[1]
    if dict1[a] != dict1[b]:
        newSet = dict1[a].union(dict1[b])
        for vertice in newSet:
            dict1[num] = newSet
        lists.append(i + 1)

check = all(dict1[x] == dict1[1] for x in dict1.keys())

if check:
    for i in lists:
        print i
else:
    print "Disconnected Graph"

代码首先为所有可能的顶点创建不相交的集合。然后对于每条边,它检查两个顶点所在的集合是否不同。如果是,则将这两个集合与联合操作相结合。组合集中的每个顶点都是新创建的组合集中的成员。如果顶点已经连接,则跳过它们。我认为我的代码的问题是必须在行中更新集合的次数:

for vertice in newSet:
    dict1[num] = newSet

是否有更快的方法来更新集合以检查它们是否相等?此操作大约需要 O(vertices^2) 时间,当有多达 100,000 个顶点时,需要的时间太长。

【问题讨论】:

  • 您是否有任何理由编写自己的 Kruskal 实现而不是使用已经编写好的实现,例如Scipy's minimum_spanning_tree?
  • @jakevdp 是因为法官不允许外部库

标签: python algorithm graph-theory minimum-spanning-tree kruskals-algorithm


【解决方案1】:

关键是为您的集合使用适当的数据结构。合并节点集并测试是否有任何两个节点在同一个集中是一个经典的计算机科学问题,称为“联合查找”。

最好的数据结构很简单,如下所述:

http://www.algorithmist.com/index.php/Union_Find

使用这种结构,您可以在几乎恒定的时间内合并集合并测试相等性,这使得您的 Kruskal 算法(为您提供预先排序的边列表)的实现几乎是线性的。

【讨论】:

    猜你喜欢
    • 2011-02-25
    • 2013-02-07
    • 2021-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-18
    • 1970-01-01
    相关资源
    最近更新 更多