修改Dijkstra算法以找到权重最大的最短路径

时间:2015-06-04 13:47:43

标签: algorithm graph nodes dijkstra weighted-graph

我需要一段代码,找到权重最大的节点之间的最短路径。例如,从A到D的最快路线,但权重最大:

  - B- --E
     /  \ /
    A    D
     \  / \
      C - -F

所以现在最短的是ABD或ACD。一旦加权,代码应该选择两个中最长的路径(反直觉,是吗?)。

我试图修改Dijkstra算法的算法,但最终我最终遍历了整个图表。谁会知道怎么做? 即使只是一个算法,所以我可以自己编码也会有很大的帮助。

2 个答案:

答案 0 :(得分:2)

  1. 从图表中的源代码(让它为s)运行BFS以查找 从s到目标t的最短路径的长度,设为d。同时标记d(s,v) - 从s到任何节点v的距离。
  2. 创建G'=(V',E')的子G,以便:v位于V' 仅当它与来源(s)的距离最多为d - d(s,v) <= d时。仅当e=(u,v)E'都在u时,v才会出现在V'
  3. 如果G*=(V*,E*)V'=V*中有(u,v),那么E*E'边缘d(s,u) < d(s,v)位于w*(u,v) = -w(u,v)
  4. 设置新的权重函数G*,并使用w*G上运行Bellman Ford
  5. st的{​​{1}}中最重的最短路径的重量为-d(t),而BF找到的路径是匹配的路径。
  6. 算法的时间复杂度为O(VE),因为Bellman-Ford是瓶颈。

    正确性证明

    声明1:从st的最短路径不包含任何周期。
    通过消除循环我们得到一条较短的路径,证明很简单。

    声明2:从st的所有最短路径都位于G'
    证明:由于从st的所有最短路径长度为d,因此我们仅删除距s的距离比d长的节点},我们只删除最短路径不需要的节点。

    权利要求3:从st的所有最短路径都在G*中。
    证明:假设我们在最短路径中删除了一些边(u,v),并让该路径为s->...->x->u->v->y->...->t。请注意,路径v->y->..->t的长度为d-d(s,u)-1(假设d(s,u)最小)
    但请注意,E*的构造,d(s,v) <= d(s,u)(否则(u,v)将不会被移除)。因此,路径s->...->v->y->...->t的距离为sd(s,v) + d-d(s,u)-1 <= d(s,u) + d - d(s,u) -1 <= d-1 - 与d的最小值相矛盾。

    权利要求4:G*中没有循环。
    证明:假设G*v1->v2->vk->v1中有一个周期。根据G'的定义,所有节点都可以从s到达。在不失一般性的情况下,让我们假设d(s,v1)对于所有其他d(s,vi)都是最小的(否则旋转索引以匹配此假设)。但是存在路径v1-> v2-> ...->&gt; vk-> v1和d(s,v1)=d(s,v1)。这意味着至少对于此路径中的一个边(vi,vi+1) d(vi) >= d(vi+1) - 这与E*的构造相矛盾,并且G *中不存在该循环。

    权利要求5:算法是正确的。

    从Bellman-Ford的正确性开始,由于G*不包含负循环(根本没有循环),BF将根据w*中的G*找到权重最小的路径。根据{{​​1}}的{​​{1}}构造,此路径是最大权重的路径。 由于w中的所有最短路径也存在于w*中(并且只有它们),因此该路径也是G中具有最大权重的最短路径。

    <强> QED

答案 1 :(得分:-1)

如果你调整你的体重,你可以使用Dijkstra。

如果您的最佳路径必须是访问最少节点的路径,则可以使用高惩罚 p 来遍历每条边并减去实际权重:

w '= p - w

必须选择高于最高权重 w max 的惩罚,以防止 w '的负值,Dijsktra不会工作。它也必须足够高,以便选择真正最短的路径。 n 节点图的 p 的良好估计可能是:

p n · w max

编辑:我的原始答案建议使用每条边的倒数权重 w '= 1 / w 而不是实际权重< em> w 作为替代方案。这不一定会给你最短的路径,但是在穿越少数边缘时权重很高的路径。这个解决方案在很多情况下都不起作用。但是,它完全独立于惩罚方法,不使用倒数值。)