维基百科 上提供了一些非常好的深度优先遍历的伪代码。这些遍历算法会给图中所有节点标上它们在遍历中出现的顺序。但是你想要在找到目标时立即返回到目标的路径。
因此,我们需要修改维基百科上的算法:
( INCORRECT ALGORITHM DELETED WHICH THE OP COMMENTED ON CORRECTLY BELOW )
以下是Python的实现:
g = {
'A': ['B', 'C', 'D'],
'B': ['C', 'E', 'F'],
'C': ['A'],
'D': ['B', 'F', 'G', 'H'],
'E': ['G'],
'F': ['A', 'F'],
'G': ['H', 'I'],
'H': [],
'I': []
}
def DFS(g, v, goal, explored, path_so_far):
""" Returns path from v to goal in g as a string (Hack) """
explored.add(v)
if v == goal:
return path_so_far + v
for w in g[v]:
if w not in explored:
p = DFS(g, w, goal, explored, path_so_far + v)
if p:
return p
return ""
assert DFS(g, 'A', 'I', set(), "") == "ABEGI"
assert DFS(g, 'A', 'E', set(), "") == "ABE"
assert DFS(g, 'B', 'B', set(), "") == "B"
assert DFS(g, 'B', 'B', set(), "") == "B"
assert DFS(g, 'A', 'M', set(), "") == ""
assert DFS(g, 'B', 'A', set(), "") == "BCA"
assert DFS(g, 'E', 'A', set(), "") == ""
这里的想法是在图g中找到从v到目标goal的路径,假设您已经沿着path_so_far的路径来到了v。 path_so_far应该在v之前结束。
如果v是目标,您可以将v添加到路径中,这就完成了。
否则,您需要探索从v发出的所有边缘,这些边缘没有已经探索过的节点在边缘的另一端。 对于这些边缘中的每一个,您可以使用当前节点和已有路径进行搜索(递归)。如果从v到目标没有路径,则返回空路径。
好处是您使用递归来“自动回溯”,因为您将增强的路径传递给递归调用。