【问题标题】:Dijkstra's Algorithm for Negative WeightsDijkstra 的负权重算法
【发布时间】:2015-04-18 08:51:50
【问题描述】:

好的,首先我知道 Dijkstra 不适用于负权重,我们可以使用 Bellman-ford 代替它。但是在一个问题中,我得到了它指出所有边的权重从 0 到 1(不包括 0 和 1)。而路径的成本其实就是产品。

所以我的想法就是拿日志。现在所有的边都是负的。现在我知道 Dijkstra 不适用于负权重,但在这种情况下,所有边都是负的,所以我们不能做点什么让 Dijkstra 起作用。

我虽然将所有权重乘以 -1,但最短路径变成了最长路径。

那么在这种情况下我是否可以避免使用 Bellman-Ford 算法。

确切的问题是:“假设对于某些应用程序,路径的成本等于路径中所有边的权重的乘积。在这种情况下,您将如何使用 Dijkstra 算法?所有边的权重是从 0 到 1(不包括 0 和 1)。”

【问题讨论】:

  • 首先我假设图是有向的。现在,如果权重在 0 和 1 之间,并且成本是通过权重的乘积来衡量的,那么您确实在寻找最长的路径。如果图中有任何循环,则相当于一个负成本循环。
  • 所以 Dijkstra 可以工作。我只需要找到最长的路径。另外,没有额外的要求,因此这就是我感到困惑的原因。
  • 您确定不想要最可能的路径吗?
  • 我已经给了你确切的问题。请阅读最后 3 行。
  • 是的,我在发表评论时已经阅读了这些内容。有些人非常精确地要求他们没有意识到自己不想要的东西。

标签: algorithm dijkstra shortest-path


【解决方案1】:

如果图表上的所有权重都在(0, 1)范围内,那么总会有一个权重小于1的循环,因此你将永远卡在这个循环中(每次通过循环减少了最短路径的总权重)。可能你误解了这个问题,你要么想找到最长的路径,要么不允许两次访问同一个顶点。无论如何,在第一种情况下,dijkstra'a 算法绝对适用,即使没有 log 修改。而且我很确定第二种情况不能用多项式复杂度来解决。

【讨论】:

  • 如果不允许我们两次访问同一个顶点怎么办?
  • @GeorgeAdams 这是我在回答中提到的第二种情况。您可以将问题简化为找到最长的路径,因此没有已知的多项式解决方案(查看这篇文章:cstheory.stackexchange.com/questions/17462/…
  • 完美答案。只是挑剔:你可以减少寻找最长的路径,这就是证明 NP 硬度的原因。
【解决方案2】:

所以你想使用一个函数,比如说F,你将应用于原始图的权重,然后使用 Dijkstra 算法,你会找到最短的产品路径。让我们也考虑下图,我们从节点A0 < x < y < 1 开始:

在上图中,F(x) 必须小于F(y),Dijkstra 的算法才能正确输出来自A 的最短路径。

现在,让我们从节点A 重新开始绘制一个稍微不同的图表:

那么 Dijkstra 的算法将如何工作?

由于F(x) < F(y),那么我们将在下一步选择节点B。然后我们将访问剩余的节点C。 Dijkstra 的算法将输出从AB 的最短路径是A -> B,从AC 的最短路径是A -> C

但从AB 的最短路径是A -> C -> B,成本为x * y < x

这意味着我们无法找到权重转换函数并期望 Dijkstra 算法在所有情况下都有效。

【讨论】:

    【解决方案3】:

    你写道:

    我想将所有权重乘以 -1,但最后是最短的 path 成为最长的路径。

    在最短和最长路径之间切换权重。所以1/3 将是35 将是1/5 等等。

    【讨论】:

    • 但是如果你反过来,它就不会再给出相同的答案了。假设你有 dist(a,c)=1, dist(a,b)=2, dist(b,c)=2。最长的路径是 a-b-c 成本 4。如果反过来,我们有 dist(a,c)=1, dist(a,b)=0.5, dist(b,c)=0.5。这里 a-b-c 和 a-c 的最短路径相同。
    【解决方案4】:

    如果您的图有循环,那么最短路径算法将找不到答案,因为这些循环总是“负循环”,正如 Rontogiannis Aristofanis 指出的那样。

    如果您的图表没有循环,您根本不必使用 Dijkstra

    如果它是有向的,它是一个 DAG,并且有线性时间最短路径算法。

    如果它是无向的,它就是一棵树,在树中找到最短路径是微不足道的。如果您的图是有向图,即使没有循环,Dijkstra 仍然无法工作,原因与它不适用于负边图一样。

    在所有情况下,Dijkstra 都是一个糟糕的算法选择。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-10-11
      • 2015-04-19
      • 1970-01-01
      • 2021-08-12
      • 2018-01-27
      • 2012-10-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多