我正在阅读有关Graph算法的内容,我发现了这两种算法。
我搜索了很多关于这一点,但没有得到任何满意的答案!
我怀疑Dijkstra算法和BFS在寻找最短路径时有什么区别?
使用BFS在图表中查找最短路径时我们做的是
我们发现所有连接的顶点,将它们添加到队列中并保持距离 从源到顶点。现在,如果我们找到一条从源到该顶点但距离更远的路径,那么我们就更新它了!
这与Dijkstra算法完全相同!然后Dijkstra和BFS有什么区别?那么为什么这些算法的时间复杂性如此不同呢?
如果有人可以借助伪代码解释它,那么我会 非常感谢!
我知道我错过了什么!请帮忙!
答案 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),因为很多边重复了两次。
考虑一下上面的图表。对上面的伪代码试运行一下,你会发现节点2和节点3被两次推入队列,而且所有未来节点的距离都更新了两次。
因此,假设如果 3 之后有更多节点,那么第一次插入 2 计算出的距离将用于所有未来节点,然后这些距离将使用节点 2 的第二次推送再次更新。与 3 相同的场景. 所以,你可以看到节点是重复的。因此,所有节点和边都不会只遍历一次。
Dijkstra 算法在这里做了一个聪明的工作......而不是在所有方向上遍历它只在最短距离的方向上遍历,从而防止重复更新距离。 因此,为了追踪最短距离,我们必须使用 priority_queue 代替普通队列。
如果您尝试使用 Dijkstra 算法再次试运行上图,您会发现节点被推送了两次,但只考虑距离较短的那个节点。
所以,所有节点只遍历一次,但由于使用了priority_queue,时间复杂度比普通BFS要高。
答案 3 :(得分:0)
使用SPFA algorithm,您可以在加权边图中获得具有普通队列的最短路径。
它是bellman-ford algorithm的变体,它还可以处理负的权重。
但不利的一面是,与Dijkstra相比,时间复杂度更差