简体   繁体   English

如何找到具有 k 个负加权边的最短路径?

[英]How to Find shortest paths with k negative weighted edges?

The problem is to find shortest paths from a start vertice to all other vertices in a directed graph .问题是在有directed graph中找到从起始顶点所有其他顶点最短路径

But the graph will have m positive weighted edges and k negative weighted edges, and it's guaranteed that negative weighted edges will be not in a cycle.但是该图将有m positive加权边和k negative加权边,并且保证负加权边不会在一个循环中。 In other words, there is no negative weighted cycle in this graph.换句话说,该图中没有负加权循环。

I tried to directly use Bellman-Ford and SPFA to solve this question but does there exists a faster way to do this?我尝试直接使用Bellman-FordSPFA来解决这个问题,但是否有更快的方法来解决这个问题?

If k is large enough, you should probably just run Bellman–Ford and call it a day.如果 k 足够大,您可能应该只运行 Bellman-Ford 并收工。

If k is small, you can borrow the re-weighting trick from Johnson's algorithm, but with a faster initialization than just running Bellman–Ford.如果 k 很小,您可以从 Johnson 算法中借用重新加权技巧,但初始化速度比仅运行 Bellman-Ford 更快。 Recall that Johnson computes a potential π(v) for each vertex and adjusts the cost of each arc vw from c(vw) to c′(vw) = c(vw) − π(v) + π(w), choosing π so that c′ is nowhere negative.回想一下,Johnson 计算每个顶点的潜在 π(v) 并将每个弧 vw 的成本从 c(vw) 调整为 c′(vw) = c(vw) - π(v) + π(w),选择 π因此 c' 无处为负。 The shortest path between s and t is the same with respect to c as with respect to c′, s 和 t 之间的最短路径对于 c 与对于 c' 相同,

Suppose that the input graph G has exactly one negative arc, let's say c(xy) < 0. Use Dijkstra's algorithm to compute distances in G − xy from y to all other vertices.假设输入图 G 恰好有一个负弧,假设 c(xy) < 0。使用 Dijkstra 算法计算 G - xy 中从 y 到所有其他顶点的距离。 Then define π(v) = distance(y, v).然后定义 π(v) = distance(y, v)。 The correctness proof follows the proof of Johnson's algorithm;正确性证明遵循约翰逊算法的证明; the arc xy can't be part of a shortest path from y because there are no negative cycles, so Dijkstra on G - xy in fact computes a shortest path tree for G.弧 xy 不能是从 y 开始的最短路径的一部分,因为没有负循环,因此 G - xy 上的 Dijkstra 实际上计算了 G 的最短路径树。

For general k, we can do this recursively.对于一般 k,我们可以递归地执行此操作。 If k = 0, run Dijkstra.如果 k = 0,则运行 Dijkstra。 Otherwise, remove a negative arc and compute shortest paths recursively instead of with Dijkstra.否则,删除负弧并递归计算最短路径,而不是使用 Dijkstra。 Once we have good values for π, run Dijkstra one more time, from the given start vertex.一旦我们有了好的 π 值,从给定的起始顶点再运行一次 Dijkstra。

The overall running time is O((k + 1) (m + n log n)) with Fibonacci heaps.斐波那契堆的总运行时间为 O((k + 1) (m + n log n))。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM