【问题标题】:Finding shortest path distances in a graph containing at most two negative edges在最多包含两个负边的图中查找最短路径距离
【发布时间】:2014-02-04 15:49:10
【问题描述】:

我得到一个有向图,其中每条边都有一个成本。利用图中最多有两个负边这一事实,我的目标是找到从给定节点 s 到所有节点的最短路径距离在V中。算法的时间复杂度应该是O(|E| + |V|*log|V|),所以我觉得需要应用Dijkstra的算法。

我猜我需要以某种方式将给定图转换为具有非负权重的新图,该图中从 s 到 v 的最短路径将等效于给定图中所需的最短路径.. 或也许我需要修改 Dijkstra 的算法?

我现在很挣扎。任何帮助将不胜感激!

【问题讨论】:

  • 假设 U 和 V 为负边,解决 4 种状态的问题:1- 路径不包含 U 和 V。2- 路径包含 U 且不包含 V。3- 路径包含 V 且不包含 U。4- 路径包含 U 和 v。

标签: algorithm graph dijkstra shortest-path


【解决方案1】:

由于 Dijkstra 的算法是贪心的,它不适用于负权重。为此,您需要一些其他算法,例如 the Bellman-Ford Algorithm

但是,如果您仍想使用 Dijkstra 算法,有一种已知方法。在这种方法中,您需要重新分配成本,使所有成本都变为正数。

为此,您可以查看 约翰逊算法。 Johnson 的算法由以下步骤组成(取自Wikipedia):

  1. 首先,将一个新节点 q 添加到图中,通过零权重边连接到其他每个节点。
  2. 其次,使用 Bellman-Ford 算法,从新顶点 q 开始,为每个顶点 v 找到从 q 到 v 的路径的最小权重 h(v)。如果这一步检测到负循环,则算法终止。
  3. 接下来,使用 Bellman–Ford 算法计算的值对原始图的边重新加权:从 u 到 v,长度为 w(u,v) 的边被赋予新的长度 w(u,v) + h(u) - h(v)。
  4. 最后,q 被移除,并使用 Dijkstra 算法在重新加权的图中找到从每个节点 s 到每个其他顶点的最短路径。

【讨论】:

    【解决方案2】:

    只是一些定义开始:

    • 设负边为n1 = (n1s, n1e)(即从顶点n1s到顶点n1e
      n2 = (n2s, n2e)

    • 将我们要查找的最短路径的起点和终点分别定义为se

    基本思路:

    以负权边的起始顶点和每个结束顶点的每个组合为起点,以负权边的结束顶点和每个起始顶点为终点,多次运行 Dijkstra 算法,并使用这些值来找到实际的最短路径。

    算法:

    • 使用 Dijkstra 算法确定以下最短路径,均不包括两个负边:

      se   = s -> e                  // shortest path from s to e
      sn1  = s -> n1s                // shortest path from s to n1
      sn2  = s -> n2s                // shortest path from s to n2
      ne1  = n1e -> e                // shortest path from n1 to e
      n1n2 = n1e -> n2s              // shortest path from n1 to n2
      ne2  = n2e -> e                // shortest path from n2 to e
      n2n1 = n2e -> n1s              // shortest path from n2 to n1
      
    • 现在只需计算最小值:

      se                             // s to e
      sn1 + n1 + ne1                 // s to n1 to e
      sn2 + n2 + ne2                 // s to n2 to e
      sn1 + n1 + n1n2 + n2 + ne2     // s to n1 to n2 to e
      sn2 + n2 + n2n1 + n1 + ne1     // s to n2 to n1 to e
      

    由于 Dijkstra 算法的运行次数恒定为 7 次,
    运行时间将为O(7(|E| + |V| log |V|)) = O(|E| + |V| log |V|)

    【讨论】:

    • 感谢您的回答。我的目标是找到从给定节点 s 到 V 中所有节点的最短路径距离。在这种情况下,e(结束顶点)是什么?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-07-03
    • 1970-01-01
    • 1970-01-01
    • 2018-03-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-30
    相关资源
    最近更新 更多