Algorithm Dijkstra';即使只有一条负权重边,s算法是否适用?

Algorithm Dijkstra';即使只有一条负权重边,s算法是否适用?,algorithm,data-structures,dijkstra,Algorithm,Data Structures,Dijkstra,如果有向图只有一条负权边且不包含负权圈,Dijkstra算法是否有效 不一定。在中,我给出了一个没有负圈和一条负边的图的例子,其中Dijkstra的算法不能产生正确的答案。因此,Dijkstra的算法在这种情况下并不总是有效 希望这有帮助 不,Dijkstra是贪婪算法。一旦它添加了一个边,它就不会向后看。 < P>不。考虑下面的简单反例,只有3个节点, s (start), a ,和 b>代码> w(S, A) = 1 w(S, B) = 2 w(B, A) = -2 该算法将首先确定A的

如果有向图只有一条负权边且不包含负权圈,Dijkstra算法是否有效

不一定。在中,我给出了一个没有负圈和一条负边的图的例子,其中Dijkstra的算法不能产生正确的答案。因此,Dijkstra的算法在这种情况下并不总是有效


希望这有帮助

不,Dijkstra是贪婪算法。一旦它添加了一个边,它就不会向后看。

< P>不。考虑下面的简单反例,只有3个节点,<代码> s <代码>(start),<代码> a <代码>,和<代码> b>代码>

w(S, A) = 1
w(S, B) = 2
w(B, A) = -2

该算法将首先确定
A
的距离(成本1),但通过
B
(成本0)到达该距离更便宜。

否。Dijkstra的算法是贪婪的。它假定路径权重严格增加

考虑下图。s→A.→E是最优的,但迪克斯特拉的将返回s→B→E


不,众所周知,Dijkstras算法不适用于负权重。
如果您需要负权重,请使用Bellman-Ford算法。

因为Dijkstra的算法是贪婪的,所以它不适用于负权重。你需要一些其他的算法,比如Bellman-Ford算法

但是,如果你仍然想使用Dijkstra的算法,有一个已知的方法。在这种方法中,您需要重新分配成本,以便所有成本都变为正值

这是:

假设从u到v有一条边。边缘的代价是代价(u,v)

定义:

new_cost(u,v) = cost(u,v) + d(u) - d(v)
这肯定是积极的,因为

d(v) < d(u) + cost(u,v)

正如其他一些答案正确指出的那样,不能将Dijkstra算法直接应用于带负边的图

如果原始图中没有负循环,有一种方法可以重新加权图边。这与第一次运行Bellman Ford算法的一个实例时使用的技术相同,以获得每个顶点
v
的权重
h(v)
。然后将每个边
w(u,v)
修改为
w(u,v)+h(u)− h(v)
这保证是正的,所以你得到一个只有正边的新图,你可以在上面运行Dijkstra算法

第十五节。从Coursera那里,我解释得比我好得多


将该技术应用于单源最短路径问题的唯一问题是,使用Bellman Ford重新称重需要
O(mn)
时间,这比Dijkstra的
O(m log(n))
慢。所以,你最好还是让贝尔曼·福特(Bellman Ford)来完成你的原始图表。

为什么Dijkstra会失败很简单

因为最短路径应该是:距离(s,vi)≤ 距离(s,vk)

例如,我们有以下图表:


A-->B的成本为2 B-->C的成本为负4,条件现在为假,因为从A到B的距离>从B到C的距离

Dijkstra的算法将使用一条负边,只要从将该负边作为输出边的节点开始。

通过从图的最小值边开始,您不能再通过考虑其他边权重(Dijkstra的算法就是这样工作的)

可能重复@JerryCoffin-我认为这不是重复。这个问题问的是Dijkstra的算法,它有一组非常特殊的负边,而最初的问题是为什么Dijkstra的算法不适用于一般的负边图。你能描述一下你从(重新设计成本)科学论文中得到的信息吗?作者因为我从一位专门研究Dijkstra算法的科学家那里听说,很多人试图用Dijkstra算法来处理负权重,但没有一个真正成功。我不是在用Dijkstra算法处理负权重。这根本不可能。我只是用数学运算来改变成本本身。如果你仔细观察,新的和旧的成本只会变化一个常数。我认为这个反例是错误的-
a
顶点将最终弹出,然后算法将松弛边缘
a-E
,因此选择的路径将如预期的那样
S->a->E
→B→E被发现了Dijkstra没有继续搜索。这就是贪婪的含义。它采用它找到的第一个解决方案,不寻找其他更好的解决方案。当所有权重都为非负时,就不会有更好的权重了。错(据我所知):我回顾了CLRS书中介绍的算法。当优先级队列为空时,算法停止。因此,当p队列中弹出
A
时,我们会像我上面所说的那样放松边缘
A->E
。如果您想要S和图中每个节点之间的最短路径,您将处理整个队列。如果你只关心从S到E的路径,你会在找到E时立即停止。也许,但经典的算法形式(即CLRS中的算法)在p队列为空时停止。我认为这是错误的;最后,
B
顶点将弹出优先级队列,然后我们将放松边缘
B->A
。请注意,当p队列为空时,算法停止@Dijkstra的消去生成一个生成树。从S到A的最短路径是
S->B->A
(权重0)。从S到B的最短路径是
S->A->B
(权重-1)。这些路径不能都在生成树中,因为它不是树。
d(v) < d(u) + cost(u,v)
= original cost of the same path + d(s') - d(t')