【问题标题】:Python and list mutability in an all-paths algorithm全路径算法中的 Python 和列表可变性
【发布时间】:2013-07-04 20:41:21
【问题描述】:

我一直在研究基于networkx's version 的python 中的全简单路径算法。目前,我要做的唯一更改是让它获取所有节点的所有路径,而无需在 O(n^2) 双循环内进行。

我相信我已经对主要算法进行了排序,但我不太习惯 Python 列表结构的可变性,我认为这就是算法混乱的原因。

我用 Java 编写了一个类似的程序,所以我知道测试图上应该有多少条路径,但我什至无法将这些数字合理地接近。

def _all_simple_paths_graph(DG, cutoff):
    uniquePaths = []
    nlist = DG.nodes()
    for source in nlist:
        uniqueTreePaths = []
        if cutoff < 1:
            return
        visited = [source]
        stack = [iter(DG[source])]
        while stack:
            children = stack[-1]
            child = next(children, None)
            if child is None:
                stack.pop()
                visited.pop()
            elif len(visited) < cutoff:
                if child not in visited:
                    visited.append(child)
                    stack.append(iter(DG[child]))
                    if visited not in uniqueTreePaths:
                        yield visited
                        uniqueTreePaths.append(visited)
            else: #len(visited) == cutoff:
                if visited not in uniqueTreePaths:
                    yield visited + [child]
                    uniqueTreePaths.append(visited)
                stack.pop()
                visited.pop()
    uniquePaths.extend(uniqueTreePaths)

谁能告诉我哪里出错了?我相信这与 visited 应该在哪里可变以及在哪里不应该改变有关。但是,我也可能把基本功能弄错了,我对 Python 还很陌生!

【问题讨论】:

    标签: python immutability graph-algorithm depth-first-search


    【解决方案1】:

    您没有具体说明症状是什么。生成的东西是错的,还是uniquePaths 错了?看起来该函数产生了正确的路径,但在函数结束时,uniquePaths 的路径远少于应有的路径,并且它们都是空的。

    路径不足的原因是uniquePaths.extend(uniqueTreePaths) 的缩进不正确。

    您遇到的问题是 visited 是一个可变列表。在 Python 中,所有列表都是可变的。事实上,这就是这个算法起作用的原因。 visited 被视为恰好是路径的堆栈。当您将visited 多次附加到uniqueTreePaths 时,您实际上是在一遍又一遍地附加同一个对象。当你修改visited时,它们都被修改了。

    要解决此问题,您应该附加列表的副本。这在内存方面将是相当昂贵的,但是您希望图中的所有唯一路径,所以您应该已经意识到这一点。您可以使用uniqueTreePaths.append(list(visited))visited 中创建一个新的list 对象。我实际上会从中创建一个元组,这样它就不能被修改:uniqueTreePaths.append(tuple(visited))

    【讨论】:

    • 感谢您指出我的可变性不正确的地方。它看起来是正确的,但我的理解是一个完整的图表应该有 n*n!简单的路径。在我的例子中,一个完整的 3 图应该是 3*3! = 18,但它只计算 15(如果包括基本情况),我只能自己计算 15。您知道算法是否错误,或者我对简单路径的了解是否错误? :)
    • 我认为 n*n!是错的。查看证明:stackoverflow.com/questions/8457805/…“停止”选择不应与节点选择相同,因此您不能只是乘法。
    • 这就是我得到 nn 的地方!公式来自,它在答案中:'and nn!图中所有可能的简单路径。
    猜你喜欢
    • 2016-06-13
    • 2015-04-21
    • 2012-09-23
    • 1970-01-01
    • 1970-01-01
    • 2017-03-07
    • 1970-01-01
    • 1970-01-01
    • 2017-01-24
    相关资源
    最近更新 更多