具有最大顶点数的最短路径
Shortest path with a maximum number of vertices
我想找到两个顶点之间的最短路径,但有一个附加约束:最多可以访问 n 个顶点。该图是有向的、连通的、非负权重的并且可能包含循环。
示例:
- 最短路径 0->2 n = 2 是 18
- 最短路径 0->3 n = 3 是 22
- 最短路径 0->3 n = 4 是 9
到目前为止我已经实现了 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
或更少的顶点。
我想找到两个顶点之间的最短路径,但有一个附加约束:最多可以访问 n 个顶点。该图是有向的、连通的、非负权重的并且可能包含循环。
示例:
- 最短路径 0->2 n = 2 是 18
- 最短路径 0->3 n = 3 是 22
- 最短路径 0->3 n = 4 是 9
到目前为止我已经实现了 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
或更少的顶点。