两者都可用于从单一来源中找到最短路径。BFS 运行于O(E+V)
,而 Dijkstra 运行于O((V+E)*log(V))
.
此外,我还看到 Dijkstra 在路由协议中的使用非常相似。
因此,如果 BFS 可以更快地做同样的事情,为什么还要使用 Dijkstra 算法呢?
两者都可用于从单一来源中找到最短路径。BFS 运行于O(E+V)
,而 Dijkstra 运行于O((V+E)*log(V))
.
此外,我还看到 Dijkstra 在路由协议中的使用非常相似。
因此,如果 BFS 可以更快地做同样的事情,为什么还要使用 Dijkstra 算法呢?
Dijkstra 允许为每一步分配除 1 以外的距离。例如,在路由中,距离(或权重)可以通过速度、成本、偏好等来分配。然后,该算法会为您提供从源到遍历图中每个节点的最短路径。
同时,BFS 基本上只是在每次迭代时将搜索扩展一个“步骤”(链接、边缘,无论您想在应用程序中调用什么),这恰好具有找到到达任何位置所需的最少步数的效果。来自您的源(“根”)的给定节点。
如果您考虑旅游网站,由于节点上的权重(距离),这些网站使用 Dijkstra 算法。
如果您会考虑所有节点之间的距离相同,那么 BFS 是更好的选择。
例如,考虑A -> (B, C) -> (F)
由A->B
= 10, A->C
= 20, B->F
= C->F
= 5 给出的边权重。
在这里,如果我们应用 BFS,答案将是 ABF 或 ACF,因为两者都是最短路径(相对于边的数量),但如果我们应用 Dijstra,答案将是 ABF,因为它考虑了连接的权重小路。
Dijkstra 算法
从实现的角度来看,Dijkstra 的算法可以通过将queue
与priority queue
.
对此存在混淆,可以使用修改后的 BFS 算法在加权有向图中找到最短路径:
由于 2,一些节点将被访问一次以上,这使得它与 Dijkstra 相比效率较低。
shortest = sys.maxsize
queue = [(0, src, 0)]
while queue:
(cost, node, hops) = heapq.heappop(queue)
if node == dst:
shortest = min(distance, cheapest)
for (node_to, node_distance) in edges[node]:
heapq.heappush(queue, (cost + node_distance, node_to, hops + 1))
请注意,这并不能解决边缘上的正权重约束,Bellman-Ford 通过支付速度惩罚来解决一个著名的缺点 Dijkstra(和 BFS)
资料来源:Erickson, Jeff (2019) 第 8.4、8.6 章。算法