Python递归DFS处理超大规模图触发递归深度限制问题求助
问题描述
我正在使用Python进行DFS(深度优先搜索),借助NetworkX库以图数据结构存储节点,数据集包含5000000个节点。之后我使用to_dict_of_lists()函数将存储的数据转换为邻接表。现在调用DFS函数时出现“maximum recursion depth limit exceeded”错误,尝试通过sys模块提升递归深度后仍报错,请问该如何解决?
附实现代码:
def DFS(graph,start,visited): if start not in visited: visited.append(start) for i in graph[start]: print(start, graph[start]) DFS(graph,i,visited) return visited
if __name__=="__main__": g = nx.DiGraph() with open('web-Google.txt', newline = '\n') as files: file_1 = csv.reader(files, delimiter='\t') for i,line in enumerate(file_1): from_node= int(line[0]) to_node= int(line[1]) g.add_edge(from_node, to_node) a = nx.to_dict_of_lists(g) #print(a) b=depth_first_search(a, 0)
解决方案
递归式DFS在处理500万节点的超大规模图时,必然会触发递归深度限制——Python默认递归深度仅1000左右,即便手动调高,也会受系统栈内存限制,最终还是会栈溢出。核心解决办法是将递归实现改为迭代实现,用栈数据结构模拟递归过程,彻底摆脱递归深度的约束。
另外你的代码还有两个关键优化点:
- 用
list存储visited时,start not in visited的时间复杂度为O(n),500万节点下会严重拖慢速度,建议换成**集合(set)**存储已访问节点,查询时间复杂度降至O(1) - 代码中的
print(start, graph[start])会输出海量内容,严重影响运行效率,建议注释或删除
迭代版DFS实现
def dfs_iterative(graph, start): visited = set() # 用栈模拟递归流程,初始栈放入起始节点 stack = [start] while stack: node = stack.pop() # 弹出栈顶节点 if node not in visited: visited.add(node) # 栈是后进先出,若需保持和递归DFS一致的遍历顺序,需将邻接节点逆序入栈 # 无需严格顺序的话,直接extend即可 stack.extend(reversed(graph[node])) # 如需返回列表格式,转换为list即可 return list(visited)
修改主函数调用
if __name__=="__main__": import csv import networkx as nx g = nx.DiGraph() with open('web-Google.txt', newline = '\n') as files: file_1 = csv.reader(files, delimiter='\t') for i,line in enumerate(file_1): from_node= int(line[0]) to_node= int(line[1]) g.add_edge(from_node, to_node) a = nx.to_dict_of_lists(g) b = dfs_iterative(a, 0)
额外优化:直接使用NetworkX内置函数
NetworkX本身提供了成熟的DFS遍历函数,比如nx.dfs_preorder_nodes(),调用库函数比自行实现更高效稳定:
# 直接调用NetworkX的DFS预序遍历 b = list(nx.dfs_preorder_nodes(g, source=0))
内容的提问来源于stack exchange,提问作者Muhammad Hani
相关产品推荐
相关产品推荐

