Algorithm 为什么要使用Dijkstra';如果广度优先搜索(BFS)可以更快地完成同样的事情,那么s算法呢?

Algorithm 为什么要使用Dijkstra';如果广度优先搜索(BFS)可以更快地完成同样的事情,那么s算法呢?,algorithm,graph,dijkstra,breadth-first-search,Algorithm,Graph,Dijkstra,Breadth First Search,两者都可用于从单个源查找最短路径。BFS在O(E+V)中运行,而Dijkstra在O((V+E)*log(V))中运行 此外,我还看到Dijkstra在路由协议中使用了很多类似的方法 因此,如果BFS可以更快地完成同样的事情,为什么要使用Dijkstra算法呢?Dijkstra允许为每一步分配除1以外的距离。例如,在路由中,距离(或权重)可以通过速度、成本、偏好等进行分配。然后,该算法将为您提供从源到遍历图中每个节点的最短路径 同时,BFS基本上只是在每次迭代中用一个“步骤”(链接,边缘,任何你

两者都可用于从单个源查找最短路径。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算法

  • 类似于加权图的BFS
  • 如果所有成本相等,Dijkstra=BFS

来源:

从实现的角度来看,Dijkstra的算法可以通过将
队列
替换为
优先级队列
来实现,就像BFS一样


关于这一点有一个困惑,可以使用改进的BFS算法在加权有向图中找到最短路径:

  • 使用优先级队列而不是普通队列
  • 不跟踪访问的节点,而是跟踪与起始节点的距离
  • 因为2,一些节点将被访问一次以上,这使得它比Dijkstra效率更低

    shortest=sys.maxsize
    队列=[(0,src,0)]
    排队时:
    (成本、节点、跃点)=heapq.heapop(队列)
    如果节点==dst:
    最短=最小(距离,最便宜)
    对于边[节点]中的(节点到,节点到距离):
    heapq.heappush(队列,(成本+节点距离,节点到,跳数+1))
    
    两者都会产生相同的结果,即两个顶点之间的路径,但只有dijkstra会保证最短路径。@jmcorter9t顺便说一句,您的注释似乎是已接受答案的第二条注释。但我想你是说谢谢你的更正。在这个链接的答案中,应该是被接受答案的第二条评论:尽管如此,这是真的吗?如果路径的成本较小,Dijkstra将重新访问节点。BFS不会重新访问节点。所以从技术上讲,交换队列和优先级队列的唯一区别并不完全相同。这是不正确的,实现是完全不同的。Dijkstra从完全初始化的优先级队列开始,除了起始节点外,所有顶点的距离都等于无穷大。BFS以包含起始节点的队列开始。