我已经查看了dijkstra算法found here的实现,但它似乎适用于负权重。
具体来说,relax方法更新优先级队列中的顶点距离,或者如果它最初不在队列中,则将其重新插入。
由于没有任何检查以确保我们不会重新插入已知的顶点,因此这种实现更像是一个Bellman-ford算法,我们不断插入顶点进行访问并放松直到减少距离的边缘?
例如:
在下面的图像上以A作为来源运行时,我们首先确定以下距离:
C = 0
B = 1
D = 99
然后在我们的队列删除后,我们留下(D,99),这使我们访问顶点D并放松它。当放松顶点D时,我们发现(D到B = -300),这使得到B的距离为-201。现在使用"放松"上面的方法,我们重新插入(B,-201)队列。现在我们取队列的最小值,即我们刚插入的(B,-201)。由此,我们放松B,我们可以到C的距离为-200。
我知道任何负面循环都会使程序无法终止,但是如果给出一个没有负循环的图形怎么办? 希望我在这里不会错过任何微不足道的事情。谢谢你的帮助!
答案 0 :(得分:0)
因为如果你输入负重,它将malloc()
答案 1 :(得分:0)
Dijkstra基于这样的事实,即一旦访问节点并且其所有边缘都“被使用”,它就不再被访问,因此复杂性很低(不需要“重新平衡整个图形”。)< / p>
这两者都是基于非负边缘,因为如果存在负面边缘,则必须“重新平衡”它们,复杂性会上升很多。正如你所提到的,负循环的循环根本不会结束。
作者抛出异常的原因是因为他不想处理“无效”图形,特别是无休止的循环。
PS:您的特定图形实际上应该可以由Dijkstra解决,但想象这个图形具有负边缘且没有周期:
A ->(1) B ->(1) -> C
| (-300)
v ^
(5) |
D ->(1) E
你真的解决了
B=1
C=2
在此之后你关闭A,B和C并且不想再次输入它们。但在此之后,您发现A-> D-> E-> B是-294,然后您重新输入所有其他值。
想象一下为什么这么糟糕,我给你另一个例子
A ->(1) B ->(1) -> C -> SUPERGRAPH
| (-999999)
v ^
(99999) |
D ->(1) E
所以现在A-&gt; D是非常高的值而C指向一些SUPERGRAPH但是从A开始总长度不超过99999。
会发生什么?即使这有效并且没有其他周期,你也可以从A中解决整个超图,但在此之后,你会发现实际上A-> B更短,你必须再次解决整个SUPERGRAPH。如果你有更多这样的情况,对于每一个,你必须再次运行Dijkstra alghoritm。