【问题标题】:Example of graph with negative weights that Dijkstra's Algorithm will work correctlyDijkstra 算法可以正常工作的负权图示例
【发布时间】:2016-05-07 15:57:27
【问题描述】:

这不是问题的另一个重复,试图理解为什么 Dijkstra 不能使用负权重。我知道为什么,但在某些特殊情况下,它会使用负权重,我正在尝试找到它们。

因此,在某些情况下,Dijkstra 可以正确处理具有负权重的图,但我找不到示例。有谁知道图表,那会起作用吗?

【问题讨论】:

  • 那么 Dijkstra 如果以直接的方式实现(每次放松一个节点,它就会被添加到 PQ)将始终有效,除非从源头可以到达一个负循环。但是对于非负数情况的运行时保证不成立,因为一个节点可以被多次处理,并且算法本质上变成了 bellmand-ford
  • @NiklasB。使用 Dijkstra 每个节点只处理一次。即使没有负循环,负权重边缘也会影响计算。这就是为什么通常负权重不起作用的原因。也许您正在考虑约翰逊的算法? en.wikipedia.org/wiki/Johnson%27s_algorithm
  • @ErickG.Hagstrom 该算法有不同的表述。在实践中,如果您使用优先级队列,则不明确跟踪您已经完成的节点是有意义的,因此您可以理论上再次放宽已完成的节点,但这永远不会发生在非负图。负权重可能会发生这种情况,但这不会损害正确性(如果没有负循环)。也许我在这里稍微扩展了“Dijkstra 算法”的概念
  • @NiklasB。好的,当然,但我认为这不再是 Dijkstra。这是另一回事。特别是,您失去了与 Dijkstra 相关的 big-O,因为您可以任意次数地访问每个顶点。
  • 是的,但只有负权重,这是我的观点。你可以称它为“Bellman-Ford 优先队列”,但实际上它只是 Dijkstra 的核心,在没有最差输入但可能只有几个负边缘的实际场景中它非常快跨度>

标签: algorithm graph dijkstra negative-number


【解决方案1】:

事实上,任何仅在源自start 的边上具有负权重的图都可以工作。负权重的问题在于,它们可能导致算法“错过”权重最低的顶点,因为它“稍后”获得了较低的权重。所以

| begin | end | weight |
|   s   |  1  |   -1   |
|   s   |  2  |   -2   |
|   1   |  3  |    1   |
|   2   |  3  |    1   |
|   3   |  t  |    1   |

应该不会给 Dijkstra 带来任何实际麻烦。

可以将其概括为更强有力的陈述:在 Dijkstra 评估之前正确计算顶点权重的任何图都将由 Dijkstra 正确处理,同时保留 Dijkstra 的时间性能。

【讨论】:

    【解决方案2】:

    Dijkstra 在负权重下工作正常的一个简单例子就是:

    s -(-1)-> t
    

    如果您在源 s 的这张图上运行 Dijkstra 算法,它将发现 t 作为最近邻并选择那个,然后我们构建了正确的最短路径树。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-12
      • 2011-10-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多