【问题标题】:Recursive Depth First Search in PythonPython中的递归深度优先搜索
【发布时间】:2015-03-20 06:43:59
【问题描述】:

所以我一直在尝试在 python 中实现深度优先搜索递归。在我的程序中,我的目标是返回父数组。 (图中顶点的父节点)

def dfs_tree(graph, start):
    a_list = graph.adjacency_list
    parent = [None]*len(a_list)
    state = [False]*len(a_list)
    state[start] = True

    for item in a_list[start]:
        if state[item[0]] == False:    
            parent[item[0]] = start
            dfs_tree(graph, item[0])
    state[start] = True

    return parent 

它表示已达到最大递归深度。我该如何解决这个问题?

【问题讨论】:

    标签: python recursion graph depth-first-search


    【解决方案1】:

    我可以看到这种行为的主要原因是在每次递归调用时重新初始化state(和parent)数组。每次遍历只需要初始化一次。常用的方法是将这些数组添加到函数参数列表中,用None 初始化它们,并在第一次调用时用列表替换:

    def dfs_tree(graph, start, parent=None, state=None):
        a_list = graph.adjacency_list
        if parent is None:
            parent = [None]*len(a_list)
        if state is None:
            state = [False]*len(a_list)
        state[start] = True
    
        for item in a_list[start]:
            if state[item[0]] == False:    
                parent[item[0]] = start
                dfs_tree(graph, item[0], parent, state)
        state[start] = True
    
        return parent
    

    之后,更改算法似乎是正确的。但问题mentioned by Esdes 仍然存在。如果要正确遍历大小为n 的图,则需要执行sys.setrecursionlimit(n + 10)10 代表dfs_tree 之外的最大嵌套函数调用数,包括隐藏的初始调用。如果需要,您应该增加它。

    但这不是最终解决方案。 Python 解释器对堆栈内存本身有一些限制,这取决于操作系统和某些设置。因此,如果您将recursionlimit 增加到某个阈值以上,那么当超出解释器的内存限制时,您将开始出现“分段错误”错误。我不记得这个阈值的确切值,但它看起来大约是 3000 次调用。我现在没有口译员要检查。

    在这种情况下,您可能需要考虑使用堆栈将算法重新实现为非递归版本,或者尝试更改 python 解释器的堆栈内存限制。

    P.S.您可能需要将if state[item[0]] == False: 更改为if not state[item[0]]:。比较布尔值通常被认为是一种不好的做法。

    【讨论】:

    • 谢谢,正是我需要的。我会努力解决你提到的问题:)
    【解决方案2】:

    要修复此错误,只需像这样增加默认递归深度限制(默认为 1000):

    sys.setrecursionlimit(2000)
    

    【讨论】:

    • 当它被炸毁时你会如何解决?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多