最多经过顶点数的最短路径

5
我希望您能够帮忙翻译以下编程相关内容:我想要找到两个顶点之间的最短路径,并有一个额外的限制条件:最多可以访问n个顶点。该图是有向的,连通的,权重为非负数,可能包含循环。

例如:

enter image description here

  1. 02的最短路径,当n=2时为18
  2. 03的最短路径,当n=3时为22
  3. 03的最短路径,当n=4时为9

目前我已经实现了Dijkstra算法来获得简单的最短路径,我的想法是保持当前访问的顶点计数器,如果超过n,则返回一步或多步并尝试另一条路径... 但据我所知,Dijkstra不能用于回溯,如此处所述。

另一个想法是以某种方式将每个节点之间的每条路径存储在表中。但我不太确定Dijkstra如何发现权重为18的路径0->2,因为它实际上不是最短路径...

有人有什么想法来解决这个问题吗?


那么,除了回溯之外,如何计算访问的顶点数量呢?可以将其作为权重的一部分来应用,每走一步权重就会增加。不过你需要想办法对其进行归一化处理。 - gidim
4个回答

5
将每个顶点分成n个顶点,即对于顶点u,我们创建表示为(u, 1) ... (u, n)的n个顶点,第二个数字显示到达该顶点的步数。对于从u到v的每条边,在新图中从(u, i)到(v, i + 1)创建一条边,其中1<=i<=n-1。现在,如果您想使用n计算u和v之间的最短路径,只需从(u, 1)开始进行Dijkstra,然后您的答案是min(result(v,i)|1<=i<=n)。
总顶点数可以是n*n,因此复杂度约为O(n^2*log(n^2))。

2

令COST_TO(v,n)表示到顶点v的n条边或更少的最小路径的总权重。

当n=0时,答案很容易:

对于所有v,如果v是源顶点,则COST_TO(v,0)=0,否则为无穷大。

对于n>0,COST_TO(v,n)是COST_TO(v,n-1)和所有COST_TO(w,n-1)+WEIGHT(w,v)中的最小值,其中有一条从w到v的边。

因此,对于n=0到N,跟踪所有COST_(v,n)<无穷大的顶点及其成本,并从n-1的值计算n的成本。

同时,您可以跟踪到每个v的最小权重路径--每次使用边规则更新v的成本时,新的到v的路径是到w再加上那条边。一个反向单向链接列表非常方便。


0

或许可以尝试使用广度优先搜索算法,并将顶点数量与最大值进行比较。保存符合约束条件的最佳结果。

这里有一个相关视频 https://youtu.be/TvHV3PB8ANs

Nist.gov 也提供了一些算法。


视频已被删除。你还记得原标题吗?或者有另一个演示该算法的指针吗? - Mu Mind

0
假设您想要找到从源顶点S到目标顶点T的最短路径,该路径由至多K条边组成。我选择了K,因为您问题中的n是误导性的 - 如果您想要找到访问至多n个顶点的最短路径,其中n是总顶点数,您可以运行Dijkstra算法,因为任何简单路径最多有n个顶点 - 我假设这不是您在这里想要的。

然后,如果您想要一个简单的实现,Bellman-Ford是一个很好的选择:

在外层循环的第 i 次迭代后,该算法已经计算出了从源顶点S到任何由至多i条边组成的其他顶点的最短路径,因此它由 最多i + 1个顶点组成。因此,为了解决您的问题,请运行Bellman-Ford的K-1个外部循环,并检查到目标顶点T的距离是否被定义(与无限大不同),如果是,则已找到结果。否则,T无法从访问K或更少个顶点的S到达。

我认为算法不一定有效。链接的维基百科页面也这样说:“在扫描边缘的每个迭代i中,算法找到所有最多长度为i的最短路径(可能还有一些超过i的路径)。” 如果您需要在$i$条边上设置硬约束,则可能会得出错误的答案。 - AniSkywalker

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接