在related thread中,有人建议我使用Dijkstra算法来查找图上的最短路径。从维基百科看这个算法的.gif文:
如果路径1,3,6,5的成本非常低,该怎么办?例如,3-6的重量是1,6-5的重量是2? Dijkstra的算法不会考虑这条路径,因为它只看向前一步;它跳过了节点3.
在选择每个节点之前,指定一个使算法看起来比2,3,4 ... n步的参数是否可以接受?我意识到这可能会耗费计算时间,但只要节点不是非常密集(即每个节点不超过3或4个连接),这可以为我们的特定数据集提供性能和最佳解决方案之间的良好折衷。 。
有没有人对此有强烈感受?并且这种可调节参数的最短路径算法是否可能在图形包中?
答案 0 :(得分:3)
它不会跳过节点3.它会这样做:
从节点1
开始,更新到邻居的距离:
d[2] = 7
d[3] = 9
d[6] = 14
选择与源最小距离的下一个未访问节点,在本例中为节点2
并更新到其邻居的距离:
d[3] = min(d[3], d[2] + c(2, 3))
= min(9, 7 + 10)
= 9
d[4] = min(d[4], d[2] + c(2,4))
= min(inf, 7 + 15)
= 22
然后它将选择3
:更新与其邻居的距离:
d[6] = min(d[6], d[3] + c(3, 6))
= min(14, 9 + 1)
= 10
然后选择距离d
最小的下一个未访问节点并执行相同操作。选择目标节点时停止。
没有必要按照你的建议做,只要边缘权重为正,算法就可以正常工作。
答案 1 :(得分:2)
Dijkstra算法总是找到最短路径(在没有负边的图中)并且永远不会回溯。它很容易推理。
考虑节点及其边缘(它只是较大图形的一部分):
6 _ 3
| /
14| /9
|/
1-------2
7
Dijkstra的算法将开始选择边1-2 (7)
。我这样做是因为它是迄今为止看到的最小值。然后,它将最短路径的值设置为2
7
。它永远不会再次更改此值,因为从1
到2
的任何其他路径必须更大(因为它必须以边1-3 (9)
或1-6 (14)
之一开始)。
推理接下来会发生什么的一种方法是假装算法合并"已知"节点成一个节点。在该示例中,只要选择到2
的最短路径,它就会将1
和2
合并为单个逻辑节点。从2
开始的所有边都增加7
(到2
的最短路径)。下一步是从"超级节点"中选择最小边缘。然后推理与第一步相同:
6 _ 3
| /
14| /9
|/
1,2-------4
22
在此状态下,下一个选定的边是1,2-3 (9)
。 3
的最短路径设置为9
,其所有边缘现在都被视为选择下一个最小值(请注意6
和4
的边缘如何更新的):
6
|
11|
|
1,2,3----4
20