图论学习笔记3

最短路径算法

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法。

猜你喜欢

转载自blog.csdn.net/rona1/article/details/79900549