寻路算法——JPS算法
一、JPS与A*
A*的缺点:扩展节点时会将周围所有节点考虑进来,当地图很大时,openList里的节点会很多,搜索效率降低。
因此我们希望可以采取一系列措施来减少放入openList里的节点,所以JPS由此而来。
JPS使用基于搜索跳点的策略来扩展后继节点,遵循“两个定义,三个规则”
下面这张图详细描述了A*和JPS的算法流程差别。
二、JPS算法的“两个定义,三个规则”
定义①:强迫邻居(Forced Neighbour)
如果节点 x 的8个邻居中有障碍,且 x 的父节点 p 经过x 到达 n 的距离代价比不经过 x 到达的 n 的任意路径的距离代价小,则称 n 是 x 的强迫邻居。
如图画红圈的就是强迫邻居。
(简单理解:以从父节点到当前节点的方向为轴将地图分为两边,如果某一边上的某一位置有障碍物,那么该障碍物的前一格(“前”是以当前方向决定))
定义②:跳点(Jump Point)
-
如果节点P是起点或者目标节点,那么P是跳点。
-
如果节点P有至少一个强迫邻居,则P是跳点。
-
如果从P的父节点到P为对角线移动,并且P经过水平或垂直方向移动可以到达跳点,则P是跳点。
规则①:当直线方向(水平方向和垂直方向)均可移动,优先在直线方向搜索跳点。
规则②:从父节点到当前节点P为直线移动,若有从父节点到P的邻居N且
不经过P
的路径且该路径小于等于
经过P
的路径,则下一步不会从P走向N。对角线一样。(
定义不好理解,头大
),我的理解:沿用上图,以当前方向为轴,两边在遇到障碍物前所有的点都满足规则②,所以不会被搜索。
(仅个人理解,不准确,要是有错误欢迎指出)。
规则③:只有跳点才会被加入到openList中。(JPS快的原因)
三、JPS大致流程:
-
openlist取一个权值最低的节点,然后开始搜索。(这些和A*是一样的)
-
搜索时,先进行 直线搜索 (4/8个方向,跳跃搜索),然后再 斜向搜索 (4个方向,只搜索一步)。如果期间某个方向搜索到跳点或者碰到障碍(或边界),则当前方向完成搜索,若有搜到跳点就添加进openlist。
跳跃搜索是指沿直线方向一直搜下去(可能会搜到很多格),直到搜到跳点或者障碍(边界)。一开始从起点搜索,会有4个直线方向(上下左右),要是4个斜方向都前进了一步,此时直线方向会有8个。
3.若斜方向没完成搜索,则斜方向前进一步,重复上述过程。
4.若所有方向已完成搜索,则认为当前节点搜索完毕,将当前节点移除于openlist,加入closelist。
5.重复取openlist权值最低节点搜索,直到openlist为空或者找到终点。
源码:
JPS算法源码
效果图:
本文介绍了JPS寻路算法的基本原理,通过对比A*算法,详细解释了JPS算法的“两个定义,三个规则”,并概述了其搜索流程,有助于提高游戏开发中的寻路效率。
3973

被折叠的 条评论
为什么被折叠?



