路径规划算法1.2图搜索算法——广度优先搜索、Dijkstra与A*寻路算法

路径规划算法1.2图搜索算法——经典的Dijkstra与A*寻路算法

  • 前言
  • 广度优先搜索
  • Dijkstra算法
    • 有权图Dijkstra算法
    • Uniform Cost Search地图寻路
  • A*算法
    • 贪婪最优搜索与启发函数
    • A*算法与启发式搜索

前言

路径规划算法1.1给出了早期的图搜索算法,可视图法(VG)。本次记录基于图搜索的两种经典寻路算法Dijkstra和A*,这两个算法深刻影响了后续的grid-based算法。

这里会借助Red Blob Games主页进行叙述。

广度优先搜索

这里又提到了广度优先搜索方法,这个概念是图论中引出的。BFS的意思就是对于图(树)上的每一个节点都要展开,并且在每个方向上的展开优先级都是一致的,每个被遍历的节点都能得到其连接信息。

路径规划算法1.2图搜索算法——广度优先搜索、Dijkstra与A*寻路算法_第1张图片
路径规划算法1.2图搜索算法——广度优先搜索、Dijkstra与A*寻路算法_第2张图片
路径规划算法1.2图搜索算法——广度优先搜索、Dijkstra与A*寻路算法_第3张图片
路径规划算法1.2图搜索算法——广度优先搜索、Dijkstra与A*寻路算法_第4张图片
以上就是从遍历全图的过程:

  • 将起点放入先进先出列表Q中。
  • 取出Q中的节点(刚开始就是起点)。
  • 访问该节点的所有邻接节点并放入Q中,(已经加入队列的节点不能再被访问),然后该节点展开完成。
  • 取出下一个节点,重复以上过程,直到没有节点再能被展开后结束。

在节点展开的过程中,如果记录下每个节点与它访问到的节点,就形成了节点之间的路径:

路径规划算法1.2图搜索算法——广度优先搜索、Dijkstra与A*寻路算法_第5张图片
作为寻路算法时,不需要将所有节点都展开,当目标节点被搜索到时就可以提前结束了:
路径规划算法1.2图搜索算法——广度优先搜索、Dijkstra与A*寻路算法_第6张图片
(图源 Red Blob Games)

Dijkstra算法

有权图Dijkstra算法

Dijkstra是一种广度优先搜索算法(Breadth-First Search, BFS),不过该Dijkstra在搜索中引入了从起点到节点的cost作为引导,因此能够在有权图中获得到达每个路点最短的路径。

路径规划算法1.2图搜索算法——广度优先搜索、Dijkstra与A*寻路算法_第7张图片

对于以上这个有权图,以A为起点,算法的流程是这样的:

  1. 建立两个队列U(记录已到达节点)、Q(未到达节点),以及一个数组array(记录从起点到其他各点的最短距离)。
  2. 初始化U={A}、Q={B,C,D,E,F}、array={5,10,15,inf,inf}(如果起点不能到达某节点,则距离记为inf)
  3. 提取Q中与A距离最近的节点s,把s放入U
  4. 更新array中的最短距离
  5. 循环3、4步骤

具体流程就是:
array中AB距离最小,从Q中取出B放入U={A,B},BE相连,array中A->B->E的距离=135 ,10,15,13,inf}
AC距离最小,从Q中取出C放入U={A,B,C},CD相连,array中A->C->D的距离14<15,更新array={5 ,10 ,14,13,inf}
AE距离最小,从Q中取出E放入U={A,B,C,E},ED、EF相连,array中A->B->E->D的距离=14=14,A->B->E->F的距离=225 ,10 ,14,13 ,22}
AD距离最小,从Q中取出D放入U={A,B,C,E,D},DF相连,array中A->B->E->D-F的距离=20<22,更新array={5 ,10 ,14,13 ,20 }
节点搜索完毕,最后U={A,B,C,E,D,F},array={5,10,14,13,20}。U中节点顺序表示两点间的最短路径,array表示A与节点间的最短距离。

Uniform Cost Search地图寻路

在地图中寻路时,更常用的方法是应用了Dijkstra思想的Uniform Cost Search算法,通过优先搜索最短距离节点、更新最小距离的方式来寻找最优路径。区别在于Dijkstra将获得地图中到达每个节点的最短路径,而Uniform Cost Search只获得到达目标点的最短路径。

如下图所示,绿色格子的cost是浅色格子的5倍,折线表示具有相同cost的节点。左右图是BFS与Dijkstra算法(实际是UCS算法)的对比。
路径规划算法1.2图搜索算法——广度优先搜索、Dijkstra与A*寻路算法_第8张图片
(图源 Red Blob Games)

A*算法

贪婪最优搜索与启发函数

Dijkstra算法在搜索节点时优先选择最小cost节点,而贪婪最优搜索Greedy Best First Search则使用了一种启发式函数作为搜索参考值:
h e u r i s t i c ( s , g o a l ) = ∥ s − g o a l ∥ heuristic(s, goal)=\|s-goal\| heuristic(s,goal)=sgoal
其中s表示搜索到的节点,goal表示目标点,|| ||表示范数。

贪婪最有搜索通过启发函数来优先搜索那些距离目标更近的节点,因此相比Dijkstra的速度要快的多:
路径规划算法1.2图搜索算法——广度优先搜索、Dijkstra与A*寻路算法_第9张图片
但是如果起点与目标间存在障碍物,则有可能找不到最优路径:

路径规划算法1.2图搜索算法——广度优先搜索、Dijkstra与A*寻路算法_第10张图片
(图源 Red Blob Games)

A*算法与启发式搜索

前面的贪婪最优搜索没有找到最佳路径的原因,就是由于搜索仅依赖于启发函数(离目标越近越好),而忽略了到达节点的cost。

因此,A*算法融合了Dijkstra和启发函数,在寻路时,搜索那些当前cost与期望的cost最小的节点,其搜索权值函数为:
f ( s ) = c o s t ( s t a r t , s ) + h e u r i s t i c ( s , g o a l ) f(s)=cost(start, s)+heuristic(s, goal) f(s)=cost(start,s)+heuristic(s,goal)

其结果如下图,可以看出Dijkstra、GBF和A*的区别,其中紫色线为cost,粉色线为heuristic.
路径规划算法1.2图搜索算法——广度优先搜索、Dijkstra与A*寻路算法_第11张图片
(图源 Red Blob Games)

你可能感兴趣的:(路径规划算法学习,算法,自动驾驶,自然语言处理)