如果有向图仅包含一个负权重边且不包含负权重循环,那么Dijkstra算法是否有效?
如果有向图仅包含一个负权重边且不包含负权重循环,那么Dijkstra算法是否有效?
不,Dijkstra算法是一种贪心算法。它假设路径权重严格递增。
考虑以下图形。S→A→E是最优的,但Dijkstra算法将返回S→B→E。
A
顶点将会最后弹出,然后算法会放松边缘 A-E
,因此选定的路径将会是预期的 S->A->E
。 - EliminationA
从优先队列中弹出时,我们将像我上面说的那样松弛边缘A->E
。 - EliminationS
(开始),A
和B
。w(S, A) = 1
w(S, B) = 2
w(B, A) = -2
A
的距离(代价为1),但是通过B
去那里更便宜(代价为0)。B
顶点将会最后从优先队列中弹出,然后我们将放松边 B->A
。请注意,算法在优先队列为空时停止! - EliminationS->B->A
(权重为0)。从S到B的最短路径是S->A->B
(权重为-1)。这些路径不能同时存在于生成树中,因为那就不是一棵树了。 - Vincent van der Weele由于Dijkstra算法是贪心算法,不能处理带有负权重的情况。您需要使用其他算法,如Bellman-Ford算法来解决这个问题。
但是,如果您仍然想使用Dijkstra算法,有一个已知的方法。在这种方法中,您需要重新分配成本,以使所有成本变为正数。
具体步骤如下:
假设存在从u到v的边缘。该边缘的成本为cost(u,v)。
u(d(u))------>v(d(v))
定义:
new_cost(u,v) = cost(u,v) + d(u) - d(v)
d(v) < d(u) + cost(u,v)
= original cost of the same path + d(s') - d(t')
希望这能帮到您!
不,Dijkstra算法是一种贪心算法。一旦它添加了一条边,就不会再回头看。
v
的权重h(v)
。然后将每个边w(u,v)
修改为w(u,v) + h(u) - h(v)
,这保证是正数,因此您最终得到一个仅包含正边的新图,您可以在上面运行Dijkstra算法。只要从具有负权出边的节点开始,Dijkstra算法即可处理单个负权边。
通过从图中最小值的边开始,你不能再通过考虑其他边权重来减少总成本(这就是Dijkstra算法的工作方式)。
为什么Dijkstra算法可能失败,很简单:
因为最短路径应该是:distance(s, vi) ≤ distance(s, vk)
例如,我们有这个图:
A---->B 距离2 B--->C 距离-4 此时条件不满足 因为A到B的距离 > B到C的距离