我尝试进行深度优先搜索以查找所有路径的列表,然后确定最短路径和最长路径。
python文档(https://www.python.org/doc/essays/graphs/)具有以下内容,需要结束节点:
def find_all_paths(graph, start, end, path=[]):
path = path + [start]
if start == end:
return [path]
if not graph.has_key(start):
return []
paths = []
for node in graph[start]:
if node not in path:
newpaths = find_all_paths(graph, node, end, path)
for newpath in newpaths:
paths.append(newpath)
return paths
我的问题是如何在没有指定结束节点的情况下找到(有向非循环)图中的所有路径?我的起始节点始终保持不变。
我可以在开始时使用for循环并遍历节点。但这并不是最有效的方式,因为如果我可以使用相同的路径重新访问节点,这将浪费计算时间。
for node in nodeList:
find_all_paths(graph, 0, node)
答案 0 :(得分:1)
您可以修改深度优先搜索代码,只需进行一些调整即可查找到所有终端节点的所有路径。
首先,删除end
参数,将基本情况放在start == end
。然后,在开始递归步骤之前,只需将path
添加到paths
即可。在递归调用中,不要再尝试传递end
。
就是这样:
def find_all_paths(graph, start, path=[]):
path = path + [start]
if not graph.has_key(start):
return [path]
paths = [path]
for node in graph[start]:
if node not in path:
newpaths = find_all_paths(graph, node, path)
for newpath in newpaths:
paths.append(newpath)
return paths
请注意,作为递归生成器,您可以更有效地执行此操作,而不是构建一个大的路径列表(我还修改了不在图中的节点的特殊检查:使用{{1}运算符比使用not in
)更好:
dict.has_key
请注意,def find_all_paths(graph, start, path=[]):
path = path + [start]
yield path
if start not in graph:
return
for node in graph[start]:
if node not in path:
yield from find_all_paths(graph, node, path)
仅适用于Python 3.3及更高版本。如果您使用的是早期版本,请使用显式循环:
yield from