最短路径:DFS,BFS或两者兼而有之?

时间:2013-02-09 03:50:08

标签: algorithm graph depth-first-search breadth-first-search

我知道BFS单独可以找到未加权图表中的最短路径,但我也读过几个人们声称BFS或DFS可以做到这一点的网站。我只想确认这些可能是错误,而且只有BFS可以做到这一点(即使在快速谷歌搜索后我也没有完全自信)。如果我不对,有人可以解释一下DFS如何能够提供最短路径。

5 个答案:

答案 0 :(得分:13)

DFS不一定在无向图中产生最短路径。 BFS将是这里的正确选择。

作为一个例子,考虑一个通过取三角形并连接它们而形成的图形。如果您尝试使用DFS找到从一个节点到另一个节点的最短路径,那么除非您遵循直接连接起始节点和目标节点的边缘,否则您将得到错误的答案。

希望这有帮助!

答案 1 :(得分:3)

迭代深化搜索(IDS),包括多轮深度限制搜索(基本上是DFS,但是如果你已达到深度限制d则停止搜索),从1逐渐增加深度,将找到最短路径未加权的图表。

// Iterative deepening search
// isGoal is a function that checks whether the current node is the goal
function ids(graph, start, isGoal) { 
    maxDepth = 1
    do {
        found = dls(graph, start, isGoal, maxDepth, 0)
        // Clear the status whether a node has been visited
        graph.clearVisitedMarker();
        // Increase maximum depth
        depth = depth + 1

    // You can slightly modify the dls() function to return whether there is a
    // node beyond max depth, in case the graph doesn't have goal node.
    } while (found == null)

    return found
}

// Depth-limited search
// isGoal is a function that checks whether the current node is the goal
function dls(graph, currentNode, isGoal, maxDepth, currentDepth) {
    if (graph.visited(currentNode)) {
        return null
    }
    graph.setVisited(currentNode)

    if (isGoal(currentNode)) {
        return currentNode
    }

    // Stop searching when exceed max depth
    // This is the only difference from DFS
    if (currentDepth >= maxDepth) {
        return null
    }

    for (adjNode in graph.getAdjacent(currentNode)) {
        found = dls(graph, adjNode, goal, maxDepth, currentDepth + 1)
        if (found != null) {
            return found
        }
    }

    return null
}

它有效,因为你逐渐增加了从起始节点允许的距离:由于深度限制,在距离为a的节点之前不会探测距离为a + 1的节点。

一个常见的问题是距离为a的节点将被重新访问(d-a + 1)次,其中d是到达目标的最短路径的深度。如果我们想谈谈性能,它取决于图形或搜索树。在具有大分支因子的搜索树上,在深度d处生成的节点成为主导项,因此重新访问没有太大问题。由于指数空间要求,BFS无法用于此类情况,但IDS仅使用多项式空间。

答案 2 :(得分:2)

要理解的观点:没有重量和方向的图表中的BFS与Dijkstra(重量= 1,一个方向)相同,因此理解Dijkstra为什么是正确的可能有所帮助。如果我完成了更多细节,将会添加更多细节。

答案 3 :(得分:0)

我知道这里的聚会迟到了,但是。 DFS 和 BFS 之间有几个区别(简短回答:它们都可以在未加权图中找到最短路径)。

  1. BFS:通常由队列实现(先进先出数据结构) 当您逐层耗尽所有相邻顶点直到到达目标节点并在该节点处停止时,例如:如果未找到所有该节点层进入队列,则从第 1 层到达所有节点,并继续为第 2 层和很快。它将保证目标节点是迄今为止找到的最短层(因为它在找到目标节点后停止,因此不会遍历图中的所有节点(速度上比DFS快))

  2. DFS:通常由栈实现(先进后出数据结构) DSF 从给定点耗尽所有节点,直到无法再探索为止。但是当它找到目标节点时,不能保证路径是最短路径,因此它必须遍历图中的所有节点以确保路径是最短的。 顺便说一句

@alandong 回答错了

答案 4 :(得分:-1)

如果你正确实施,BFS和DFS都会给出从A到B的最短路径。

让我们将整个图表视为一棵树。基本上,BFS将运行每个级别的树并通过遍历所有级别找出路径。相比之下,DFS将运行到每个叶节点,并在沿该路径遍历节点时找出路径。它们都使用排气路径搜索搜索,因此,如果您正确实施这些算法,它们都将保证找到最短路径。

使用BFS和DFS的优缺点如下:

BFS,使用更多内存,遍历所有节点

DFS,使用更少的内存,如果您幸运地选择包含您感兴趣的节点的叶节点路径,则可能会稍快一些。(不一定要遍历所有节点)。