最短路径算法-迪杰斯特拉算法图解

在搬运之前 onenote 里面的笔记,这里补一篇迪杰斯特拉算法图解,也当作复习一下。

算法步骤

  1. 每次从未标志节点中选择距离起点最近的节点,然后标志已检查; 
  2. 计算刚标志的节点 A 到未标志的邻近节点 B 的距离,若节点 A 的距离 a +节点 A 到节点 B 的距离 ab < 节点 B 的距离 b。更新节点 B 的距离 b=a+ab,更新节点 B 的路径父节点为节点 A; 
  3. 检查完所有节点,从目标节点的父节点往前遍历,便得到起点到终点的最短路径; 

图解

标志列表:记录检查过的节点。
距离列表:记录节点到起点的最短距离,初始化全是无穷大。
父节点列表:记录节点的最短距离路径父节点。

在图示中,水平和纵向栅格移动代价为 2,斜向代价为 3。绿色栅格表示起始节点,紫色栅格表示障碍物,红色栅格表示目标节点。

迭代 0 :初始化,标志列表为空,距离列表记录的距离为无穷大,父节点列表各节点父节点为空。

在初始化后,需要先更新起始节点的距离信息为 0。

迭代 1 :在未标志的节点中,起始节点 00 的距离信息最小。

  1. 标志离起始节点最近的节点,也就是起始节点 00 本身。
  2. 更新附近节点 01,05,06 的距离信息,再更新其父节点为节点 00。

迭代 2 :在未标志的节点中,节点 01 和节点 05 距离信息最小,都是 2。

  1. 按下标顺序,先标志节点 01。
  2. 更新节点 01 附近节点 00,02,05,06,07 的距离信息。
    1. 其中节点 00 已经标志过了,不需要更新。
    2. 节点 02,07 被障碍物占据,距离信息仍是无穷大。
    3. 节点 05 距离信息 (d05=2) < 节点 01 距离 (d01=2) + 节点间距离 (d0105=3) 的距离,节点 05 距离信息不更新。
    4. 节点 06 距离信息 (d06=3) < 节点 01 距离 (d01=2) + 节点间距离 (d0106=2) 的距离,节点 06 距离信息不更新。
  3. 距离信息没有更新,父节点也不需要更新。

迭代 3 :在未标志的节点中,节点 05 距离信息最小。

  1. 标志节点 05。
  2. 更新节点 05 附近节点 00,01,06,10,11 的距离信息。
    1. 其中节点 00,01 已经标志过了,不需要更新。
    2. 节点 06 距离信息 (d06=3) < 节点 05 距离 (d05=2) + 节点间距离 (d0506=2) 的距离,节点 05 距离信息不更新。
    3. 节点 10 距离信息 d10 更新为节点 05 距离 (d05=2) + 节点间距离 (d0510=2) = 4。
    4. 节点 11 距离信息 d11 更新为节点 05 距离 (d05=2) + 节点间距离 (d0511=3) = 5。
  3. 更新节点 10,11 父节点为节点 05。

迭代 4 :在未标志的节点中,节点 06 距离信息最小。

  1. 标志节点 06。
  2. 更新节点 06 附近节点 00,01,02,05,07,10,11,12 的距离信息。
    1. 其中节点 00,01,05 已经标志过了,不需要更新。
    2. 节点 02,07 被障碍物占据,距离信息仍是无穷大。
    3. 节点 10 距离信息 (d10=4) < 节点 06 距离 (d06=3) + 节点间距离 (d0610=3) 的距离,节点 10 距离信息不更新。
    4. 节点 11 距离信息 (d11=5) = 节点 06 距离 (d06=3) + 节点间距离 (d0611=2) 的距离,节点 11 距离信息不更新。
    5. 节点 12 距离信息 d12 更新为节点 06 距离 (d06=3) + 节点间距离 (d0612=3) = 6。
  3. 更新节点 12 父节点为节点 06。

迭代 5 :在未标志的节点中,节点 10 距离信息最小。

  1. 标志节点 10。
  2. 更新节点 10 附近节点 05,06,11 的距离信息。
    1. 其中节点 05,06 已经标志过了,不需要更新。
    2. 节点 11 距离信息 (d11=5) < 节点 10 距离 (d10=4) + 节点间距离 (d1011=2) 的距离,节点 11 距离信息不更新。
  3. 距离信息没有更新,父节点也不需要更新。

迭代 6 :在未标志的节点中,节点 11 距离信息最小。

  1. 标志节点 11。
  2. 更新节点 11 附近节点 05,06,07,10,12 的距离信息。
    1. 其中节点 05,06 ,10 已经标志过了,不需要更新。
    2. 节点 07 被障碍物占据,距离信息仍是无穷大。
    3. 节点 12 距离信息 (d12=6) < 节点 11 距离 (d11=5) + 节点间距离 (d1112=2) 的距离,节点 12 距离信息不更新。
  3. 距离信息没有更新,父节点也不需要更新。

迭代 7 :在未标志的节点中,节点 12 距离信息最小。

  1. 标志节点 12。
  2. 更新节点 12 附近节点 06,07,08,11,13 的距离信息。
    1. 其中节点 06 ,11 已经标志过了,不需要更新。
    2. 节点 07 被障碍物占据,距离信息仍是无穷大。
    3. 节点 08 距离信息 d08 更新为节点 12 距离 (d12=6) + 节点间距离 (d1208=3) = 9。
    4. 节点 13 距离信息 d13 更新为节点 12 距离 (d12=6) + 节点间距离 (d1213=2) = 8。
  3. 更新节点 08,13 父节点为节点 12。

迭代 8 :在未标志的节点中,节点 13 距离信息最小。

  1. 标志节点 13。
  2. 更新节点 13 附近节点 07,08,09,12,14 的距离信息。
    1. 其中节点 12 已经标志过了,不需要更新。
    2. 节点 07 被障碍物占据,距离信息仍是无穷大。
    3. 节点 08 距离信息 (d08=9) < 节点 13 距离 (d13=8) + 节点间距离 (d1308=2) 的距离,节点 08 距离信息不更新。
    4. 节点 09 距离信息 d09 更新为节点 13 距离 (d13=8) + 节点间距离 (d1309=3) = 11。
    5. 节点 14 距离信息 d14 更新为节点 13 距离 (d13=8) + 节点间距离 (d1314=2) = 10。
  3. 更新节点 09,14 父节点为节点 13。

迭代 9 :在未标志的节点中,节点 08 距离信息最小。

  1. 标志节点 08。
  2. 更新节点 08 附近节点 02,03,04,07,09,12,13,14 的距离信息。
    1. 其中节点 12,13 已经标志过了,不需要更新。
    2. 节点 02,07 被障碍物占据,距离信息仍是无穷大。
    3. 节点 09 距离信息 (d09=11) = 节点 08 距离 (d08=9) + 节点间距离 (d0809=2) 的距离,节点 09 距离信息不更新。
    4. 节点 14 距离信息 (d14=10) < 节点 08 距离 (d08=9) + 节点间距离 (d0814=3) 的距离,节点 14 距离信息不更新。
    5. 节点 03 距离信息 d03 更新为节点 08 距离 (d08=9) + 节点间距离 (d0803=2) = 11。
    6. 节点 04 距离信息 d04 更新为节点 08 距离 (d08=9) + 节点间距离 (d0804=3) = 12。
  3. 更新节点 03,04 父节点为节点 08。

迭代 10 :在未标志的节点中,节点 14 距离信息最小。

  1. 标志节点 14。
  2. 更新节点 14 附近节点 08,09,13 的距离信息。
    1. 其中节点 08,13 已经标志过了,不需要更新。
    2. 节点 09 距离信息 (d09=11) = 节点 14 距离 (d14=10) + 节点间距离 (d1409=2) 的距离,节点 09 距离信息不更新。
  3. 距离信息没有更新,父节点也不需要更新。

迭代 11 :在未标志的节点中,节点 03,09 距离信息最小。

  1. 按下标顺序,先标志节点 03。
  2. 更新节点 03 附近节点 02,04,07,08,09 的距离信息。
    1. 其中节点 08 已经标志过了,不需要更新。
    2. 节点 02,07 被障碍物占据,距离信息仍是无穷大。
    3. 节点 04 距离信息 (d04=12) < 节点 03 距离 (d03=11) + 节点间距离 (d0304=2) 的距离,节点 04 距离信息不更新。
    4. 节点 09 距离信息 (d09=11) < 节点 03 距离 (d03=11) + 节点间距离 (d0309=3) 的距离,节点 09 距离信息不更新。
  3. 距离信息没有更新,父节点也不需要更新。

迭代 12 :在未标志的节点中,节点 09 距离信息最小。

  1. 标志节点 09。
  2. 更新节点 09 附近节点 03,04,08,13,14 的距离信息。
    1. 其中节点 03,08,13,14 已经标志过了,不需要更新。
    2. 节点 04 距离信息 (d04=12) < 节点 09 距离 (d09=11) + 节点间距离 (d0904=2) 的距离,节点 04 距离信息不更新。
  3. 距离信息没有更新,父节点也不需要更新。

此时已经标志了目标节点 09 了!目标节点的最短路径已经检查结束!

在父节点列表中,从节点 09 的父节点往前遍历,得到 09 -> 13 -> 12 -> 06 -> 00 的最短路径。

迭代 13 :在未标志的节点中,节点 04 距离信息最小。

  1. 标志节点 04。
  2. 更新节点 04 附近节点 03,08,09 的距离信息。
    1. 其中节点 03,08,09 已经标志过了,不需要更新。
  3. 距离信息没有更新,父节点也不需要更新。

最后剩下的未标志节点都是障碍物。全地图遍历结束,从起始节点到地图任意可达节点的最短路径都获得了。

思考

  • 节点距离概念泛化

迪杰斯特拉算法中,节点的距离不仅可以看作是欧氏距离,还可以看作是移动成本。例如给地图增加障碍物距离信息,节点离障碍物越近,移动成本越大。这样迪杰斯特拉算法遍历搜索的得到路径就不是最短路径,而是移动成本最低的路径,路径离障碍物距离得当且距离相对较短。

  • 一定要遍历完所有节点吗?

当“未标记节点中距离起点最近的点”中存在目标点,例如图解的迭代 11,此时就可以直接标志目标节点,得到目标最短路径了。

  • 24
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值