Python 中的递归深度优先搜索
Recursive Depth First Search in Python
所以我一直在尝试在python中实现深度优先搜索递归。在我的程序中,我的目标是 return 父数组。 (图中顶点的父级)
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
表示已达到最大递归深度。我该如何解决这个问题?
要修复此错误,只需像这样增加默认递归深度限制(默认为 1000):
sys.setrecursionlimit(2000)
我所看到的这种行为的主要原因是在每次递归调用时重新初始化 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
改算法后似乎是正确的。但是问题 依然存在。如果你想正确遍历大小为 n
的图,你需要做 sys.setrecursionlimit(n + 10)
。 10
表示 dfs_tree
之外的最大嵌套函数调用数,包括隐藏的初始调用。如果需要,您应该增加它。
但这不是最终的解决方案。 Python 解释器对堆栈内存本身有一些限制,这取决于 OS 和一些设置。因此,如果您将 recursionlimit
增加到某个阈值以上,当超出解释器的内存限制时,您将开始收到 "segmentation fault" 错误。我不记得这个阈值的确切近似值,但它看起来大约是 3000 次调用。我现在没有翻译可以检查。
在这种情况下,您可能需要考虑使用堆栈将算法重新实现为非递归版本,或者尝试更改 python 解释器的堆栈内存限制。
P.S. 您可能需要将 if state[item[0]] == False:
更改为 if not state[item[0]]:
。比较布尔值通常被认为是一种不好的做法。
所以我一直在尝试在python中实现深度优先搜索递归。在我的程序中,我的目标是 return 父数组。 (图中顶点的父级)
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
表示已达到最大递归深度。我该如何解决这个问题?
要修复此错误,只需像这样增加默认递归深度限制(默认为 1000):
sys.setrecursionlimit(2000)
我所看到的这种行为的主要原因是在每次递归调用时重新初始化 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
改算法后似乎是正确的。但是问题n
的图,你需要做 sys.setrecursionlimit(n + 10)
。 10
表示 dfs_tree
之外的最大嵌套函数调用数,包括隐藏的初始调用。如果需要,您应该增加它。
但这不是最终的解决方案。 Python 解释器对堆栈内存本身有一些限制,这取决于 OS 和一些设置。因此,如果您将 recursionlimit
增加到某个阈值以上,当超出解释器的内存限制时,您将开始收到 "segmentation fault" 错误。我不记得这个阈值的确切近似值,但它看起来大约是 3000 次调用。我现在没有翻译可以检查。
在这种情况下,您可能需要考虑使用堆栈将算法重新实现为非递归版本,或者尝试更改 python 解释器的堆栈内存限制。
P.S. 您可能需要将 if state[item[0]] == False:
更改为 if not state[item[0]]:
。比较布尔值通常被认为是一种不好的做法。