负权重使用Dijkstra的算法

我试图理解为什么Dijkstra的算法不能使用负权重。阅读一个关于Shortest Paths的例子,我想弄清楚下面的情况:

    2
A-------B
 \     /
3 \   / -2
   \ /
    C

从网站:

Assuming the edges are all directed from left to right, If we start
with A, Dijkstra’s algorithm will choose the edge (A,x) minimizing
d(A,A)+length(edge), namely (A,B). It then sets d(A,B)=2 and chooses
another edge (y,C) minimizing d(A,y)+d(y,C); the only choice is (A,C)
and it sets d(A,C)=3. But it never finds the shortest path from A to
B, via C, with total length 1.

我不明白为什么使用Dijkstra的下面的实现,d [B]不会更新为1(当算法到达顶点C时,它将运行一个放松B,看到d [B]等于2,因此将其值更新为1)。

Dijkstra(G, w, s)  {
   Initialize-Single-Source(G, s)
   S ← Ø
   Q ← V[G]//priority queue by d[v]
   while Q ≠ Ø do
      u ← Extract-Min(Q)
      S ← S U {u}
      for each vertex v in Adj[u] do
         Relax(u, v)
}

Initialize-Single-Source(G, s) {
   for each vertex v  V(G)
      d[v] ← ∞
      π[v] ← NIL
   d[s] ← 0
}

Relax(u, v) {
   //update only if we found a strictly shortest path
   if d[v] > d[u] + w(u,v) 
      d[v] ← d[u] + w(u,v)
      π[v] ← u
      Update(Q, v)
}

谢谢,

Meir

您建议的算法将确实找到此图中的最短路径,但不是一般的所有图。例如,考虑这个图表:

假设边缘从左到右定向,如在示例中,

您的算法将工作如下:

>首先,将d(A)设置为零,将其他距离设置为无穷大。
>然后展开节点A,将d(B)设置为1,将d(C)设置为零,将d(D)设置为99。
>接下来,展开C,没有净变化。
>然后展开B,这没有效果。
>最后,展开D,将d(B)更改为-201。

注意,在这末尾,尽管d(C)仍然为0,即使到C的最短路径长度为-200。因此,在某些情况下,您的算法无法准确计算距离。此外,即使你要存储回指针,说明如何从每个节点到达起始节点A,你将结束采取从C到A的错误路径。

http://stackoverflow.com/questions/6799172/negative-weights-using-dijkstras-algorithm

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:负权重使用Dijkstra的算法