DFS用于查找两个节点之间是否存在路由

时间:2017-05-23 08:33:42

标签: python algorithm graph depth-first-search

我正在尝试实施DFS,但在此方面遇到了一些麻烦。

首先,我设法得到一个简单的DFS示例,它只是在访问节点时打印出来。

def DFS_helper(self, node, visited):
    if node == None:
        return

    print(node.val)
    visited.append(node)

    for child in self.getChildren(node):
        if child not in visited:
            self.DFS_helper(child, visited)


def DFS(self, node):
    visited = []
    return self.DFS_helper(node, visited)

请注意,在上面的代码示例中,我执行了self.DFS_helper...而不是return语句。为什么是这样?

现在,我正在尝试确定图表中的两个节点是否可访问。这是我的尝试。

def _isReachable(self, nodeA, nodeB, visited, stack):
    if len(stack) == 0:
        return False

    if nodeA == nodeB:
        return True

    front = stack.pop(0)
    visited.add(front) # mark the node as visited

    for neighbor in nodeA.neighbors:
        if neighbor not in visited: # if it's not already been visited
            stack.append(neighbor)
            return self._isReachable(neighbor, nodeB, visited, stack)

# given a directed graph, returns true if there is a route from nodeA to nodeB
# Returns false otherwise
# this method essentially runs a DFS from nodeA to nodeB
def isReachable(self, nodeA, nodeB):
    if nodeA == None or nodeB == None:
        return False
    if nodeA == nodeB:
        return True

    stack = [nodeA]
    visited = set()
    return self._isReachable(nodeA, nodeB, visited, stack)

它不仅不起作用,我不太清楚我理解调用递归函数和返回它的结果之间的区别。我试过两种方式都没有用。我非常感谢您对代码和概念上的任何帮助!

1 个答案:

答案 0 :(得分:2)

问题出在你的退货声明中:

return self._isReachable(neighbor, nodeB, visited, stack)

在这里,你在找到第一个孩子的结果后中断,而不是聚合所有孩子的结果。

看看这个例子:

source: a
target: d

      a
    /   \
  /       \
 b          c
            |
            |
            d

现在,如果您在(a,b)之前通过(c,d)遍历图表,则此返回语句将意味着您不会探索c然后d,您将会答案d未连接。

要解决此问题,您需要返回_isReachable(b,...) or _isReachable(c,...)

(当然,每个节点有两个以上的孩子来概括)