这段Python代码是否使用深度优先搜索(DFS)寻找所有路径?

2 投票
3 回答
4223 浏览
提问于 2025-04-16 07:22

这段代码来自于Python官方的图论文章。代码如下:

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

我对Python还不太熟练,因为我还没有足够的练习和阅读。你能不能把这段代码和深度优先搜索(DFS)图中的兄弟姐妹概念联系起来解释一下?谢谢。

3 个回答

1

是的,这个算法确实是深度优先搜索(DFS)。注意,当它遍历不同的节点时,会立刻进入子节点进行递归,这和广度优先搜索(BFS)不一样。广度优先搜索会先列出所有可以访问的节点,比如同一层级的节点(也就是兄弟节点),然后只有在这些节点不符合要求时才会进行递归。

4

考虑一下以下的修改和执行脚本:

def find_all_paths(graph, start, end, path=[]):
    path = path + [start]
    print 'adding %d'%start
    if start == end:
        return [path]
    if not graph.has_key(start):
        return []
    paths = []
    for node in graph[start]:
        if node not in path:
            paths.extend(find_all_paths(graph, node, end, path))
    print 'returning ' + str(paths)
    return paths

G = {1:[2,3,4], 2:[1,4], 3:[1,4], 4:[1,2,3]}
find_all_paths(G, 1, 4)

输出结果:

adding 1
adding 2
adding 4
returning [[1, 2, 4]]
adding 3
adding 4
returning [[1, 3, 4]]
adding 4
returning [[1, 2, 4], [1, 3, 4], [1, 4]]

注意到第一个路径在加3之前就返回了,而第二个路径在加4之前就返回了。

4

要理解这是深度优先搜索(DFS),关键在于递归发生在路径累积之前。换句话说,递归会一直深入,直到需要的深度,然后才会把任何东西放到“路径”列表里。在返回列表之前,所有最深的兄弟节点都会被累积到“路径”中。

我认为代码使用“append”是正确的,而不是“extend”,因为“路径”是所有路径的累积器。不过,它可能也可以写成

paths += find_all_paths(graph, node, end, path)

(编辑)...而不是

 newpaths = find_all_paths(graph, node, end, path)
 for newpath in newpaths:
     paths.append(newpath)

撰写回答