Dijkstra 算法可以在权重为 0 的图上工作吗?

dan*_*oll 6 algorithm dijkstra breadth-first-search path-finding

如果存在一个加权图 G,并且所有权重都是0,那么 Dijkstra 算法是否仍然找到最短路径?如果是这样,为什么?

根据我对算法的理解,如果没有边权重,Dijsktra 的算法将像正常的BFS一样运行,但我希望得到一些澄清。

Zab*_*uza 8

解释

0根据算法的定义,Dijkstra 本身在权重方面没有问题。它只会在权重时出现问题。

因为在每一轮中,Dijkstra 都会结算一个节点。如果您稍后发现负权重边,这可能会导致通往该已解决节点的路径更短。然后需要使节点不稳定,这是 Dijkstras 算法不允许的(并且会破坏算法的复杂性)。如果你看一下实际的算法和一些插图,就会很清楚。

Dijkstra 在这种全零图上的行为与所有边都具有不同但相同的值一样1(结果最短路径长度除外)。Dijkstra 将简单地访问所有节点,没有特定的顺序。基本上,就像一个普通的广度优先搜索


细节

看看维基百科的算法描述:

 1 function Dijkstra(Graph, source):
 2
 3     create vertex set Q
 4
 5     for each vertex v in Graph:           // Initialization
 6         dist[v] ? INFINITY                // Unknown distance from source to v
 7         prev[v] ? UNDEFINED               // Previous node in optimal path from source
 8         add v to Q                        // All nodes initially in Q (unvisited nodes)
 9
10     dist[source] ? 0                      // Distance from source to source
11      
12     while Q is not empty:
13         u ? vertex in Q with min dist[u]  // Node with the least distance
14                                           // will be selected first
15         remove u from Q 
16          
17         for each neighbor v of u:         // where v is still in Q.
18             alt ? dist[u] + length(u, v)
19             if alt < dist[v]:             // A shorter path to v has been found
20                 dist[v] ? alt 
21                 prev[v] ? u 
22
23     return dist[], prev[]
Run Code Online (Sandbox Code Playgroud)

负值的问题在于行1517。当您删除 node 时u,您就解决了它。也就是说,你说到这个节点的最短路径现在是已知的。但这意味着您不会u再次将其视为17某个其他节点的邻居(因为它不再包含在其中Q)。

对于负值,您以后可能会找到到该节点的较短路径(由于负权重)。您需要u在算法中再次考虑并重新执行所有依赖于之前最短路径的计算u。因此,您需要添加uQ该节点中删除的每个其他节点都u在其最短路径上返回到Q.

特别是,您需要考虑可能通向目的地的所有边,因为您永远不知道某些讨厌的-1_000_000加权边隐藏在哪里。

下面的例子说明了这个问题:

在此处输入图片说明

Dijkstra 会将红色路径声明为从A到 的最短路径C,长度为0。但是,还有一条更短的路径。它被标记为蓝色,长度为99 - 300 + 1 = -200

使用负权重,您甚至可以创建更危险的场景,即负循环。这是图中总权重为负的循环。然后你需要一种方法来停止一直沿着循环移动,无休止地降低你当前的体重。


笔记

在无向图中,0可以消除带权重的边并合并节点。它们之间的最短路径将始终具有 length 0。如果整个图只有0权重,那么这个图就可以合并到一个节点上。每个最短路径查询的结果很简单0

如果在两个方向上都有这样的边,则有向图也是如此。如果没有,您将无法进行该优化,因为您会更改节点的可达性。