具有最大顶点数的最短路径

Shortest path with a maximum number of vertices

我想找到两个顶点之间的最短路径,但有一个附加约束:最多可以访问 n 个顶点。该图是有向的、连通的、非负权重的并且可能包含循环。

示例:

  1. 最短路径 0->2 n = 218
  2. 最短路径 0->3 n = 322
  3. 最短路径 0->3 n = 49

到目前为止我已经实现了 Djikstras 算法来获得简单的最短路径,我的想法是保留一个当前访问的顶点的计数器,如果它超过 n 它需要退一步或多步并尝试另一条路径..但​​据我所知,Djikstras 不能用于回溯 .

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

有没有人知道如何解决这个问题?

将每个顶点分成n个顶点,即对于顶点u,我们创建n个顶点表示为(u, 1) ... (u, 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))

也许可以尝试 bfs 并根据最大值检查顶点数。保存满足约束条件的最好的。

这是一个关于它的视频 https://youtu.be/TvHV3PB8ANs

Nist.gov 也有一些算法。

设COST_TO(v,n)为到顶点v且边数不超过n条的最小路径的总权重。

当n=0时,答案很简单:

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

对于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) < infinity 的顶点及其成本,并根据 n-1 的值计算 n 的成本。

同时,您可以跟踪到每个 v 的最小权重路径——每次使用边规则更新 v 的成本时,到 v 的新路径是到 w 的路径加上该边。反向单向链表对此很方便。

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

那么,如果你想要一个简单的实现,这里Bellman-Ford是一个不错的选择:

在外循环i-th次迭代后,算法已经计算出从源顶点S到任何其他由at most i edges组成的顶点的最短路径,因此它由在 at most i + 1 vertices。因此,为了解决您的问题,运行 K - 1 Bellman-Ford 的外部循环,并检查到目标顶点 T 的距离是否定义明确(不同于无穷大),并且如果是,你就有了你的结果。否则,T 无法从 S 访问 K 或更少的顶点。