找到所有路径而不指定端节点?

时间:2015-10-18 08:53:18

标签: python graph

我尝试进行深度优先搜索以查找所有路径的列表,然后确定最短路径和最长路径。

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) 

1 个答案:

答案 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
相关问题