当前位置: 首页 > 知识库问答 >
问题:

基于队列的Bellman-Ford算法

黄泰宁
2023-03-14

我在试图理解这个算法是如何工作的。

给定一个问题,搜索从源s到图中所有顶点的路径,

我想我必须这样做:

if no cycle in the graph: 
     topological sort of the graph 
     one iteration to calculate the shortest path

else if there is a cycle in the graph:
     put s in the queue 
     v=q.deque
     while q is not empty
        relax v

我的问题是:

我的程序是好的还是我必须改变它。

当我必须检查是否存在负循环时?非常感谢。

共有2个答案

公冶和豫
2023-03-14

我不记得贝尔曼福特的细节,但基本上,假设你有n边和m顶点,

for e = 1 to n-1
     iterate tru each vertex and apply the formula

这一部分可以很容易地在互联网上找到。

当我必须检查是否存在负循环时,与相关 ,您将再进行一次迭代,如果最后一个数组(第n-1次迭代后的数组)中的任何值发生变化,您将说存在负循环,如果没有变化,则表示没有负循环。

这个youtube链接用一个例子很好地解释了贝尔曼·福特。

督坚白
2023-03-14

非循环路径的代码似乎是正确的,但这取决于您所说的计算最短路径的一次迭代是什么意思。。如果图是非循环的(即DAG),那么拓扑排序将允许我们访问每个顶点v一次(在检查其所有前辈之后),并将dist[v]更新到其最小距离。这是在线性时间O(ve)内完成的。因此,您的DAG算法应该与此类似

  DAG_CASE:   
  topological sort of V
  for each u\in V following the topological sorting
    for each edge (u,v)
      relax(u,v) 

对于有向循环图的代码(没有负循环),您没有放松边,也没有更新/检查其endpoint。。我不熟悉BF算法的排队版本。我所能说的就是,当您意识到它的一个前辈(即u)尚未完成时,您需要确保顶点v在队列中。因此,在某些条件下(在放松边的同时),代码应该排队出列一些顶点。我想你已经知道了算法的非排队版本,这是显而易见的。

当我必须检查是否存在负循环时?

通过一个源代码的BF算法返回从代码到其他顶点的最短路径,或者返回一个失败,表明有一个负循环。执行后,如果有一个边缘没有放松,那么就有一个负循环。

 类似资料:
  • 有了贝尔曼-福特的算法,稍有改变:在第7行,我们把

  • 我正在做一个有向图的项目,其中边的权重都依赖于变量x。我试图找到x的最小值,这样我的图就不包含任何正权重的回路。 我的问题是——这可能很愚蠢,但我不明白如何——:我如何使用改良的贝尔曼-福特来检查正电路而不是负电路的存在? 谢谢。

  • 假设有一个具有

  • 我如何在Bellman-Ford算法中证明这一点: 如果没有负权重循环,则从源到接收器的每个最短路径最多有边,其中是图中的顶点数。 有什么想法吗?

  • 我的讲师提到: 尝试减少循环1一次迭代的运行时间:只考虑可能给出有效松弛操作的边缘。 •如果自上次减少d[v]以来,从v引出的边尚未松弛,则顶点v处于活动状态。 •仅对从活动顶点引出的边执行“松弛”。 •在队列数据结构中存储活动顶点。 我的问题是,FIFO队列如何加速Bellman Ford的迭代?你在什么情况下“排队”?

  • 我试图解决算法简介中的问题24-1,它指的是Yen对Bellman Ford algirithm的优化,我在wiki中找到了介绍,改进: Yen的第二个改进首先在所有顶点上分配一些任意的线性顺序,然后将所有边的集合划分为两个子集。第一个子集Ef包含所有边(vi, vj),使得i 不幸的是,我不能证明至少两个边松弛距离的方法如何匹配正确的最短路径距离:一个来自Ef,一个来自Eb。