我如何解释这个回溯代码?

How do I interpret this backtracking code?

我很难理解回溯代码。特别是,我知道当我们找不到解决方案时,我们总是探索和回溯,但我不明白 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) 

printAllPathsUtil 每次调用都会收到一个指向当前 path 对象的指针。对 printAllPathsUtil 的新调用始终基于迄今为止的路径未探索且有效的基础。如果递归函数发现,它已经到达目的地 d,那么它会打印出完整的当前路径并后退一步,即路径的最后一个顶点被切断,算法会尝试寻找替代方案d 的路径(假设你的图没有重复的顶点,那么它必须是一个有 1 个以上顶点的 "detour")。否则,尚未到达 d,您将继续探索所有从 u 出去但不在 path 的顶点(因此您不会返回您来自的地方)。这一直持续到所有可能的路径离开你的初始 s 已经被测试。

在整个过程中,path 仅在可能进行更多递归时才 扩展 并且 修剪 以便 回溯到更早的状态。换句话说,您通过图形执行 depth-first-search,在每个顶点后分支(即使只有 1 个)。该算法总是先穷尽所有可能的路径,然后再回溯,因此 append-ing 和 pop-ing 是跟踪进度的正确方法。