Python中的递归深度优先搜索

时间:2015-03-20 06:43:59

标签: python recursion graph depth-first-search

所以我一直在尝试在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 

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

2 个答案:

答案 0 :(得分:0)

我可以看到这种行为的主要原因是每次递归调用时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]]:。比较布尔值通常被认为是一种不好的做法。

答案 1 :(得分:-1)

要修复此错误,只需增加默认的递归深度限制(默认情况下为1000):

sys.setrecursionlimit(2000)