路径规划算法1.1给出了早期的图搜索算法,可视图法(VG)。本次记录基于图搜索的两种经典寻路算法Dijkstra和A*,这两个算法深刻影响了后续的grid-based算法。
这里会借助Red Blob Games主页进行叙述。
这里又提到了广度优先搜索方法,这个概念是图论中引出的。BFS的意思就是对于图(树)上的每一个节点都要展开,并且在每个方向上的展开优先级都是一致的,每个被遍历的节点都能得到其连接信息。
在节点展开的过程中,如果记录下每个节点与它访问到的节点,就形成了节点之间的路径:
作为寻路算法时,不需要将所有节点都展开,当目标节点被搜索到时就可以提前结束了:
(图源 Red Blob Games)
Dijkstra是一种广度优先搜索算法(Breadth-First Search, BFS),不过该Dijkstra在搜索中引入了从起点到节点的cost作为引导,因此能够在有权图中获得到达每个路点最短的路径。
对于以上这个有权图,以A为起点,算法的流程是这样的:
具体流程就是:
array中AB距离最小,从Q中取出B放入U={A,B},BE相连,array中A->B->E的距离=13
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的距离=2210 ,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与节点间的最短距离。
在地图中寻路时,更常用的方法是应用了Dijkstra思想的Uniform Cost Search算法,通过优先搜索最短距离节点、更新最小距离的方式来寻找最优路径。区别在于Dijkstra将获得地图中到达每个节点的最短路径,而Uniform Cost Search只获得到达目标点的最短路径。
如下图所示,绿色格子的cost是浅色格子的5倍,折线表示具有相同cost的节点。左右图是BFS与Dijkstra算法(实际是UCS算法)的对比。
(图源 Red Blob Games)
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)=∥s−goal∥
其中s表示搜索到的节点,goal表示目标点,|| ||表示范数。
贪婪最有搜索通过启发函数来优先搜索那些距离目标更近的节点,因此相比Dijkstra的速度要快的多:
但是如果起点与目标间存在障碍物,则有可能找不到最优路径:
前面的贪婪最优搜索没有找到最佳路径的原因,就是由于搜索仅依赖于启发函数(离目标越近越好),而忽略了到达节点的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.
(图源 Red Blob Games)