在寻找最短路径时,BFS和Dijkstra的算法有什么区别?

时间:2014-08-22 14:46:39

标签: algorithm graph

我正在阅读有关Graph算法的内容,我发现了这两种算法。

我搜索了很多关于这一点,但没有得到任何满意的答案!

我怀疑Dijkstra算法和BFS在寻找最短路径时有什么区别?

使用BFS在图表中查找最短路径时我们做的是

我们发现所有连接的顶点,将它们添加到队列中并保持距离 从源到顶点。现在,如果我们找到一条从源到该顶点但距离更远的路径,那么我们就更新它了!

这与Dijkstra算法完全相同!然后Dijkstra和BFS有什么区别?那么为什么这些算法的时间复杂性如此不同呢?

如果有人可以借助伪代码解释它,那么我会 非常感谢!

我知道我错过了什么!请帮忙!

4 个答案:

答案 0 :(得分:74)

广度优先搜索只是Dijkstra的算法,所有边权重都等于1.

Dijkstra的算法在概念上是广度优先搜索,尊重边缘成本。

在这两种情况下,探索图表的过程在结构上是相同的。

答案 1 :(得分:2)

  

块引用   使用BFS在图表中查找最短路径我们所做的是   我们发现所有连接的顶点,将它们添加到队列中,并保持从源到该顶点的距离。现在,如果我们找到一条从源到该顶点但距离更远的路径,那么我们就更新它了!

我们在BFS中没有保持距离。它用于发现节点。 所以我们将它们放在一个通用队列中并弹出它们。与Dijikstra不同的是,我们将节点的累积权重(放松后)放入优先级队列并弹出最小距离。

所以BFS会像dijikstra一样在等重量图中工作,因为。

复杂性因使用简单队列和优先级队列而异。

答案 2 :(得分:1)

Dijkstra 和 BFS,都是相同的算法。正如其他成员所说,Dijkstra 使用 priority_queue 而 BFS 使用队列。不同之处在于两种算法计算最短路径的方式不同。

在 BFS 算法中,为了找到最短路径,我们在所有方向上遍历并分别更新距离数组。基本上,伪代码如下:

distance[src] = 0;
q.push(src);

while(queue not empty) {
    pop the node at front (say u)

    for all its adjacent (say v)
        if dist[u] + weight < dist[v]  
             update distance of v 
             push v into queue
}

上面的代码还将给出加权图中的最短路径。但是时间复杂度不等于正常的 BFS,即 O(E+V)。时间复杂度超过 O(E+V),因为很多边重复了两次。

Graph-Diagram

考虑一下上面的图表。对上面的伪代码试运行一下,你会发现节点2和节点3被两次推入队列,而且所有未来节点的距离都更新了两次。

BFS-Traversal-Working

因此,假设如果 3 之后有更多节点,那么第一次插入 2 计算出的距离将用于所有未来节点,然后这些距离将使用节点 2 的第二次推送再次更新。与 3 相同的场景. 所以,你可以看到节点是重复的。因此,所有节点和边都不会只遍历一次。

Dijkstra 算法在这里做了一个聪明的工作......而不是在所有方向上遍历它只在最短距离的方向上遍历,从而防止重复更新距离。 因此,为了追踪最短距离,我们必须使用 priority_queue 代替普通队列。

Dijkstra-Algo-Working

如果您尝试使用 Dijkstra 算法再次试运行上图,您会发现节点被推送了两次,但只考虑距离较短的那个节点。

所以,所有节点只遍历一次,但由于使用了priority_queue,时间复杂度比普通BFS要高。

答案 3 :(得分:0)

使用SPFA algorithm,您可以在加权边图中获得具有普通队列的最短路径。

它是bellman-ford algorithm的变体,它还可以处理负的权重。

但不利的一面是,与Dijkstra相比,时间复杂度更差