【问题标题】:Can Dijkstra's Algorithm work on a graph with weights of 0?Dijkstra 算法可以在权重为 0 的图上工作吗?
【发布时间】:2018-03-24 01:51:12
【问题描述】:

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

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

【问题讨论】:

    标签: algorithm dijkstra breadth-first-search path-finding


    【解决方案1】:

    说明

    根据算法的定义,Dijkstra 本身对0 权重没有任何问题。只有权重才会有问题。

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

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


    详情

    看看Wikipedia的算法描述:

     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[]
    

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

    对于负值,您稍后可能会发现到该节点的路径更短(由于负权重)。您需要在算法中再次考虑u,并重新执行依赖于u 的先前最短路径的所有计算。因此,您需要添加u 以及从Q 中删除的所有其他节点,这些节点在最短路径上具有u,返回Q

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

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

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

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


    注意事项

    在无向图中,权重为0 的边可以消除,节点可以合并。它们之间的最短路径总是长度为0。如果整个图只有0 权重,那么图可以只合并到一个节点。每个最短路径查询的结果只是0

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

    【讨论】:

    • 很好的答案,但这条线不太正确“Dijkstra 在这种全零图上的行为与所有边都具有不同但相同的值,如 1 相同” ,例如A--1--B--1--C--1--D 从 A 到 D 的距离为 3,但全零表示每个节点的距离相同。
    • @IanMercer 虽然这是正确的,但 Dijkstra 算法的行为仍然相同。就它以何种顺序访问哪些节点等而言。这就是我想在这里说的 :) 但是谢谢,我会编辑。
    • 你的最后一段:节点只能在无向图中合并(或者如果节点在两个方向上以权重0连接)
    猜你喜欢
    • 2016-05-07
    • 1970-01-01
    • 1970-01-01
    • 2016-01-11
    • 1970-01-01
    • 2021-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多