修改的最短路径算法
Posted
技术标签:
【中文标题】修改的最短路径算法【英文标题】:Modified shortest path algorithm 【发布时间】:2014-04-11 20:44:23 【问题描述】:我一直在寻找解决方案,但被卡住了。
我需要在无向图中找到最短路径。作为输入,我得到了一组无向边(x,y,p)
,其中x
和y
是节点,p
是x
和y
之间的边的权重。
路径的长度定义为每个节点的相邻边之间的绝对差之和。
边缘示例:
1 2 1
1 3 5
2 4 5
3 4 5
4 6 2
从1
到6
有多个路径:
1 -> 2 -> 4 -> 6 weight = |5 - 1| + |2 - 5| = 7
1 -> 3 -> 4 -> 6 weight = |5 - 5| + |2 - 5| = 3
因此最短路径的长度为3
,应该是算法的输出。
【问题讨论】:
权重是节点还是边?听起来您有节点权重并使用绝对差作为边权重。在这种情况下,您可以使用 Dijkstra。 权重在边缘,在练习中定义为计算节点 f.e y 的权重,其中存在路径 x->y->z 然后 y 的权重 =|xy -yz| (xy 是 x 和 y nddes 之间的边的权重) 但是你有正权重。您可以在找到最短路径之前转换图表。 我说我不知道权重是否为正 :) 我对权重和周期一无所知 您使用绝对差来查找路径的成本,因此您具有非负权重,因为绝对差是非负的。 【参考方案1】:您可以在边缘而不是节点上使用 Dijkstra,它会起作用。设s
为源节点,t
为目标。 w(i,j)
是边缘的权重(i,j)
。
d(i,j) = infinity for all edges (i,j)
q = new empty priority queue, ordered by d
for all edges (s,x):
d(s,x) = 0
insert (s,x) into q
while q is not empty:
(x,y) = q.dequeue
for all edges (y,z):
if z != x and d(x,y) + |w(x,y) - w(y,z)| < d(y,z):
d(y,z) = d(x,y) + |w(x,y) - w(y,z)|
insert (y,z) into q
结果将是边缘(x,t)
的最小距离。如果优先级队列实现为二进制堆,则运行时为O(m * log m)
。
【讨论】:
【参考方案2】:要解决此类问题,您可以使用最小/最大流量类型的方法。
对于每个节点,您都有两种可能的条件:您要么知道到达该节点的最快方式,要么不知道。因此,您可以使用数字标记每个节点,如果不知道该节点的最低成本是多少,则可以使用 null 标记。
一开始你只知道与起始节点相邻的节点的成本最低,所以你填写。
现在,向前传播,您可以找出与这些节点相邻的节点的最低成本,依此类推,直到您填满整个图表。
【讨论】:
问题是,如果我不知道路径上的下一个节点,我真的不知道相邻节点的成本。我需要知道 3 个节点来计算路径权重。 很好,那么在这种情况下,您计算距离起始节点两步远的每个节点的最小值并从那里向前传播。原理是一样的。 对于任何此类问题,请在纸上创建一个重要的示例,然后手动填写最小值。这就像数独。手动完成后,应该清楚如何编写程序来完成它。 一个节点的成本也取决于你接下来要走的边缘,所以像在 dijkstra 中那样聚合路径前缀是不够的。您将问题简化到与原始问题不再有任何关系的程度,然后您毫无根据地说将完全不相关的想法应用于最大流量等问题很容易。我不明白这有什么帮助。你考虑过这个吗?l @Niklas B.Gah,又是 Niklas。首先,对于测试值是两条边组合的任何图形,您可以将图形转换为新图形,其中新图形中的每条边都等同于原始图形中可能的边组合。所以,你当然可以通过转换图形和使用 Warshall 来解决这个问题。其次,我上面描述的方法效果很好,并且比进行图形转换要容易一些。这两种方法都与 Djikstra 算法无关。以上是关于修改的最短路径算法的主要内容,如果未能解决你的问题,请参考以下文章
数据结构与算法图最短路径算法 ( Floyed 算法 | 图最短路径算法使用场景 | 求解图中任意两个点之间的最短路径 | 邻接矩阵存储图数据 | 弗洛伊德算法总结 )