最短路径算法
1.Dijkstra算法
顶点:1,2,3,4,5,6
D=[[0,7,9,inf,inf,14],
[7,0,10,15,inf,inf],
[9,10,0,11,inf,2],
[inf,15,11,0,6,inf],
[inf,inf,inf,6,0,9],
[14,inf,2,inf,9,0]] #inf表示正无穷
求1到5最短距离
1)初始化
一个装遍历完的点的容器S,目前S={1}
一个装未遍历点的容器U,目前U={2,3,4,5,6}
一个记录1到各个点最短距离的字典,最短距离先叫做Dis吧
{2:7, 3:9, 4:inf, 5:inf, 6:inf} #不知道的先写inf,这里的距离可能在后面步骤中被不断修改。
2)从U中选一个Dis最短的点,目前是2。2与U中3、4相邻,则3,4的dis可能需要修改。先计算点3, 1->2->3=17>9,不需要修改3的dis。再计算4,1->2->4=22<inf,修改4的dis为22。2遍历完了,移到S中。
3)重复2),直到U中无点。为了记录下最短路径,可记录每次修改Dis时的路径。
2. Floyd算法
还是上面的例子
1)初始化
邻接矩阵D0=[[0,7,9,inf,inf,14],
[7,0,10,15,inf,inf],
[9,10,0,11,inf,2],
[inf,15,11,0,6,inf],
[inf,inf,inf,6,0,9],
[14,inf,2,inf,9,0]]
路径矩阵P0=[[0,1,2,3,4,5],
[0,1,2,3,4,5],
[0,1,2,3,4,5],
[0,1,2,3,4,5],
[0,1,2,3,4,5],
[0,1,2,3,4,5]]
2)k=1 to 5 遍历点计算
首先k=1时,若从0点必须经过点1到达各点,看这样的路径是否比原来的路径短,若更短,则修改D和P中的值。
生成新的D和P。
0->0不需改,0->1不需改,
原0->2=9, 现在0->1->2=7+10=17>9 不改
原0->3=inf 现在0->1->3=7+15=22<inf改
原0->4=inf 现在0->1->4=7+inf=inf不改
原0->5=14 现在0->1->5=7+14=21>14不改
D1=[[0,7,9,22,inf,14],
[7,0,10,15,inf,inf],
[9,10,0,11,inf,2],
[22,15,11,0,6,inf],
[inf,inf,inf,6,0,9],
[14,inf,2,inf,9,0]]
P1=[[0,1,2,1,4,5],
[0,1,2,3,4,5],
[0,1,2,3,4,5],
[1,1,2,3,4,5],
[0,1,2,3,4,5],
[0,1,2,3,4,5]]
基于D1和P1,再去遍历点2,以此类推。
3)最终一共得到5个D和5个P,D5中是真正的最小距离,P0到P5记录了最小路径。
3.A*算法
f(n)=g(n)+h(n)
f(n)是评价函数值,
g(n)是起点到点n的真实最短距离,一般用Dijkstra方法计算,
h(n)是点n到终点的启发式代价函数值。可以是曼哈顿距离、对角线距离、欧氏距离等。
当起点到终点太远,地图太复杂时,完全用Dijkstra求最短距离太耗时,所以就用A*算法。
先搜索起点到终点之间的某些点n的最短路径,而从n到终点的用近似的h(n)代替,用两者加和近似来评价此路径的代价,从而找到相对最佳的路径。
所以当h(n)=0时,就等价于Dijkstra法。