我很难理解回溯代码。特别是,我知道我们总是在找不到解决方案时进行探索和回溯,但是我不理解path.pop()
行背后的逻辑。
我知道我们必须在探索之后弹出元素,但是如何弹出正确的元素呢?
在此之前,我们可能一直递归到子节点
# If current vertex is not destination
#Recur for all the vertices adjacent to this vertex
for i in self.graph[u]:
if visited[i]==False:
self.printAllPathsUtil(i, d, visited, path)
那么我们如何保证path.pop()
删除u
而不删除其他节点?当我绘制一个递归树时这很有意义,但是有一种更简单的方法来理解它吗?
'''A recursive function to print all paths from 'u' to 'd'.
visited[] keeps track of vertices in current path.
path[] stores actual vertices and path_index is current
index in path[]'''
def printAllPathsUtil(self, u, d, visited, path):
# Mark the current node as visited and store in path
visited[u]= True
path.append(u)
# If current vertex is same as destination, then print
# current path[]
if u ==d:
print path
else:
# If current vertex is not destination
#Recur for all the vertices adjacent to this vertex
for i in self.graph[u]:
if visited[i]==False:
self.printAllPathsUtil(i, d, visited, path)
# Remove current vertex from path[] and mark it as unvisited
path.pop()
visited[u]= False
# Prints all paths from 's' to 'd'
def printAllPaths(self,s, d):
# Mark all the vertices as not visited
visited =[False]*(self.V)
# Create an array to store paths
path = []
# Call the recursive helper function to print all paths
self.printAllPathsUtil(s, d,visited, path)
答案 0 :(得分:0)
printAllPathsUtil
每次调用都会收到指向您当前path
对象的指针。对printAllPathsUtil
的新调用始终是基于迄今为止尚未探索和有效的路径进行的。如果递归函数找到了到达目的地d
的位置,则它将打印出完整的当前路径并退后一步,即,路径的最后一个顶点被切除,算法尝试寻找其他路径d
的路径(假设您的图形没有重复的顶点,则该路径必须是具有1个以上顶点的“绕道”)。否则,d
尚未到达,您将继续探索从u
出来的所有顶点,这些顶点已经不在path
中(因此您将不返回原点)。一直进行下去,直到测试出从初始s
出的所有可能路径为止。
在此过程中,path
仅扩展了 ,并尽可能进行了递归,并进行了修剪,以便回溯到较早的状态。换句话说,您在图形中执行depth-first-search,在每个顶点之后分支(即使只有1个)。该算法始终会在回溯之前先耗尽所有可能的路径,因此append
-ing和pop
-ing是跟踪您进度的正确方法。