概述

  • 单源最短路径法: 就是从某一个节点到 其他所有节点 的最短路径的计算。
  • 不能处理负权边,但是可以将负权边全部加上一个数变成正数。
  • 适合有向无环图。

执行步骤

需要的数据结构

  • 一个保存图的结构,用于保存节点的邻居关系;
  • 一个保存节点是否已经得到最短路径,找到最短路劲的节点标记为已处理节点;
  • 保存节点目前获得的最短路径值(默认为最大值inf)及其父节点(便于后面反推路径)。

步骤

  • 从起点开始,从邻居中找出代价最低的节点,那么最短时间到达这个节点的代价就求出 来了。标记该节点为已处理节点,更新该节点的最小代价值。
  • 找出未处理的所有节点中,代价值最小的节点,计算这个节点到其邻居的代价值。将 代价值和这些邻居原有的代价值比较,选择较小的代价值并更新其代价值和父节点。 重复该过程,直到对图中每个节点都这么做了(实际使用时,只要目标点标记为已处理 就可以停止了)。
  • 计算最终路径: 从目标点开始,依次寻找其父节点,最终连成线,就是最短路径了。

例子

如下图的树状图,线段数值表示代价值,节点0是起点。

python 机器人路径规划算法 机器人路径规划算法书_python 机器人路径规划算法

Figure 1: 图

节点

0

1

2

3

4

5

6

7

当前最小代价值

0

inf

inf

inf

inf

inf

inf

inf

当前父节点

 

 

 

 

 

 

 

 

是否已处理

true

false

false

false

false

false

false

false

初始时有上表,算法中不断更新该表。

  • a) 找出节点0的邻居(1,2),计算对应代价值(1,5),代价值比默认inf小,于是更新代价 值和父节点,找出未处理的节点中最小的代价值是1,将其标记为已处理:

节点

0

1

2

3

4

5

6

7

当前最小代价值

0

1

5

inf

inf

inf

inf

inf

当前父节点

 

0

0

 

 

 

 

 

是否已处理

true

true

false

false

false

false

false

false

  • b) 最小代价值是节点1,找出其邻居(3,4),更新代价值(11,10)和父节点(代价值比原有 值大就忽略):

节点

0

1

2

3

4

5

6

7

当前最小代价值

0

1

5

11

10

inf

inf

inf

当前父节点

 

0

0

1

1

 

 

 

是否已处理

true

true

false

false

false

false

false

false

  • c) 找出未处理节点(2,3,4)中代价最小的节点2,将其标记为已处理, 再找出节点2的邻居 重复步骤2, 直到所有节点都已标记为已处理(或者目标点标记为已处理):

节点

0

1

2

3

4

5

6

7

当前最小代价值

0

1

5

11

10

inf

inf

inf

当前父节点

 

0

0

1

1

 

 

 

是否已处理

true

true

true

false

false

false

false

false

下面将所有步骤进行完:

  • 节点2的邻居(5,6),更新代价值及父节点(6/p=2,7/p=2), 未处理的最小代价是节点 5标记为已处理:

节点

0

1

2

3

4

5

6

7

当前最小代价值

0

1

5

11

10

6

7

inf

当前父节点

 

0

0

1

1

2

2

 

是否已处理

true

true

true

false

false

true

false

false

  • 节点5的邻居(7),更新代价值及父节点(11/p=5), 未处理的最小代价是节点6标记为 已处理:

节点

0

1

2

3

4

5

6

7

当前最小代价值

0

1

5

11

10

6

7

11

当前父节点

 

0

0

1

1

2

2

5

是否已处理

true

true

true

false

false

true

true

false

  • 节点6的邻居(7),更新代价值及父节点(13>11不更新), 未处理的最小代价是节点4标记为 已处理:

节点

0

1

2

3

4

5

6

7

当前最小代价值

0

1

5

11

10

6

7

11

当前父节点

 

0

0

1

1

2

2

5

是否已处理

true

true

true

false

true

true

true

false

  • 节点4的邻居(5,7),更新代价值及父节点(13>6不更新,14>11不更新), 未处理的最 小代价是节点3和7标记为 已处理:

节点

0

1

2

3

4

5

6

7

当前最小代价值

0

1

5

11

10

6

7

11

当前父节点

 

0

0

1

1

2

2

5

是否已处理

true

true

true

true

true

true

true

true

所有节点都已处理,结束。

  • d) 查找路径,从目标点依次找父节点,知道起始点,得到路径。比如要查询到节点7 的路径: 7->5->2->0(得到路径0,2,5,7)。如果找到节点4的:4->1->0(路径0,1,4)。

总结

  • Dijkstra 保证当前选出的代价最小的节点与起点之间的路径总是最优的,(不管后面), 所以到目标点时可以保证起点和目标点的路径也是最优的。
  • Dijkstra 其实是以 breadth-first 的方法。
  • Dijkstra 不能处理负权边的情况, 这时候可以先将所有节点的权重加上一个值使权重变 为正数,或者使用 Bellman-Ford 算法。
  • 在Grid-map中使用
  • A* 算法的比较
  • Dijkstra 算法简称D算法,D* 算法全称是Dynamic A* 算法(是D算法和A*算法的结合)