编者:Tony
日期:2021-12-30
说明:本文主要介绍JPS算法的原理
一、背景
JPS(jump point search)算法实际上是对A* 寻路算法的一个改进,因此在阅读本文之前需要先了解A*算法。A* 算法在扩展节点时会把节点所有邻居都考虑进去,这样openlist中点的数量会很多,搜索效率较慢。
在无遮挡情况下(往往会有多条等价路径),而我们希望起点到终点实际只取其中一条路径,而该路径外其它节点可以没必要放入openlist(不希望加入没必要的邻居)。
其次我们还希望直线方向上中途的点不用放入openlist,如果只放入每段直线子路径的起点和终点,那openlist又可以少放很多没必要的节点:
可以看到 JPS 算法搜到的节点总是“跳跃性”的,这是因为这些关键性的节点都是需要改变行走方向的拐点,因此这也是 Jump Point 命名的来历。
二、概念
自然邻居:如图所示,红色块是自然邻居。
被迫邻居:点x的8个邻居中有障碍,n不是x的自然邻居,且x的父亲节点p(x)经过x到达n的距离代价比不经过x到达的n的任意路径的距离代价小,则称n是x的被迫邻居。这其中隐含了对p(x)的描述,最完整的表述应该是,n是x在x的父亲节点是p(x)的情况下的被迫邻居。见图示。
跳点:基于点x(当前点为x),且搜索方向为d(斜向或水平或垂直),点y满足一下三个条件之一,那么y就是跳点。
a.节点y是终点,那么节点y是跳点。
b.节点y至少有一个被迫邻居,那么节点y是跳点。
c.如果d是斜向搜索,如果节点y的水平或垂直方向上有满足条件a,b的点,那么节点y是跳点。注:节点y的水平或垂直方向是斜向向量的拆解,比如向量d=(1,1),那么水平方向则是(1,0),并不会往左搜索,只会看右边,如果向量d=(-1,-1),那么水平方向是(-1,0),只会搜索左边,不看右边,其他同理。![]()
红色块为自然邻居,黑色块为障碍物,绿色块为被迫邻居
黑色色块表示障碍物,橙色色块表示当前节点(current),绿色色块表示上一点(Parent),而黄色色块就是current节点的Forced Neighbor。从parent节点水平跳跃到current节点,这时current节点上方被障碍物挡住了,使路径parent→current→Forced Neighbor成为了parent节点和Forced Neighbor节点间的最短路径,current节点也就成为了从parent节点到Forced Neighbor节点的