找到通过一些任意节点序列的最短路径?

时间:2011-09-06 03:50:01

标签: algorithm graph shortest-path graph-algorithm dijkstra

this earlier question中,OP询问如何在图中找到从u到v的最短路径,并且还通过某个节点w。接受的答案非常好,就是运行Dijkstra算法两次 - 一次从u到w,一次从w到v。这时间复杂度等于两次调用Dijkstra算法,即O(m + n log n)。

现在考虑一个相关的问题 - 给你一个节点序列u 1 ,u 2 ,...,u k 和想要找到从u 1 到u k 的最短路径,使路径通过u 1 ,u 2 ,...,u k 按顺序排列。显然,这可以通过运行Dijkstra算法的k-1个实例来完成,每个相邻顶点对应一个,然后将最短路径连接在一起。这需要时间O(km + k n log n)。或者,您可以使用像Johnson算法这样的全对最短路径算法来计算所有最短路径,然后在O(mn + n 2 log n)时间内将适当的最短路径连接在一起,这很好因为k大于n。

我的问题是,当k很小时,是否有一种解决这个问题的算法比上述方法更快。这样的算法存在吗?或者迭代Dijkstra的效果如何?

4 个答案:

答案 0 :(得分:4)

不是运行Dijkstra算法的孤立实例来一次找到一条路径u(k) -> u(k+1),而是可以在序列中的每个节点同时启动修改后的Dijkstra类搜索的单个实例,其中包含路径当搜索区域遇到“中间”时形成。

与对Dijkstra算法进行一系列隔离调用相比,这可能会减少访问边的总数并减少边的重新遍历。

一个简单的例子就是找到两个节点之间的路径。扩展关于两个节点的搜索区域比仅扩展一个节点更好。在统一图形的情况下,第二个选项将给出半径等于节点之间距离的搜索区域,第一个选项将给出两个半径区域 - 两个整体搜索区域。

只是一个想法。

编辑:我想我正在谈论bi-directional search的多向变体,其方向与序列{u(1), u(2), ..., u(m)}中的节点一样多。

答案 1 :(得分:1)

我看不出我们怎么能做得更好,这就是我所能想到的。假设图是无向的,从任何节点u到节点v的最短路径将与从v到u的最短路径相同(当然相反)。

现在,对于u1 u2 u3 .. un的最短路径的情况,我们可以在u2上运行Djikstra算法(并在一次运行中找到最短路径u1-u2,u2-u3),然后在u4上(对于u3-u4和u4-u5),然后是u6 ..等等。这减少了你将Djikstra应用大约一半的次数。请注意复杂性,这与原始解决方案相同。

答案 2 :(得分:0)

从分而治之的角度来看你的问题,给定具有n个节点的图G,其中k [1 <= k <= n]我们想要从1-k(i1,i2, ...,IK),

假设f(j)是从i1到ij的最短路径。问题很好地细分(你已经看到了它的去向)到较小的寻找最短路径的实例,最终变成f(j)的总和,当j从1变为k。因此,您的问题受到Djikstra算法的k-1次迭代的最小限制。改进它的唯一方法是找到比Djikstra更快的算法来发现2点之间的最短路径。

至少这是我的看法。 /研究生

答案 3 :(得分:0)

通过一次调用Dijkstra算法,您可以获得图中另一个顶点到 all 的最短路径。因此,您只需要搜索每个唯一起始顶点,这样重复的顶点就不会使问题变得更难。