JPS寻路算法

JPS(Jump Point Search)是一种针对A*寻路算法的优化,减少了openlist中的节点数量,提高搜索效率。它通过找到障碍物的强制邻居和跳点来加速路径查找。在直线和斜向搜索中,当遇到跳点时将其加入openlist。相比于A*,JPS在多数情况下更快,但仅适用于网格节点环境,不支持Navmesh或路径点寻路。
摘要由CSDN通过智能技术生成

JPS寻路算法是啥?
JPS全称是:jump point search,这个算法实际上是对A* 寻路算法的一个改进,A* 算法在扩展节点时会把节点所有邻居都考虑进去,这样openlist中点的数量会很多,搜索效率较慢。
那么JPS多做了啥事呢?
在一次寻路过程中主动寻找障碍,通过障碍的位置计算出:经过障碍代价最小的一些关键位置,并将这些位置中代价最小的点作为下一次寻路过程的起点。

【参考文章:传送门
【这里有演示动画:传送门

先介绍几个概念:
1.强迫邻居:
就是指某个节点(x)上下左右有障碍,在由某方向经过这个节点的时候,如果有方向的分量垂直于障碍的方向,则在障碍一侧的斜向点就是节点(x)的强迫邻居

如上图所示,有两个要素:
a.带有搜索方向(剪头)
b.带有障碍(上下左右都行)

private Dir HaveStrictNeigh(Vector2 cur, Dir dir)
{
    bool c1, c2;
    switch (dir)
    {
        case Dir.Left:
            c1 = !IsValidPos(MoveDir(cur, Dir.Up)) && IsValidPos(MoveDir(cur, Dir.UpLeft))&& IsValidPos(MoveDir(cur, Dir.Left));
            c2 = !IsValidPos(MoveDir(cur, Dir.Down)) && IsValidPos(MoveDir(cur, Dir.DownLeft))&& IsValidPos(MoveDir(cur, Dir.Left));
            if (c1 && c2)
            {
                return Dir.Left;
            }
            else if (c1)
                return Dir.UpLeft;
            else if (c2)
            {
                return Dir.DownLeft;
            }
            break;
                   
        case Dir.Up:

2.跳点
跳点需要满足下面三个条件之一:
a.节点是寻路的起点/终点
b.节点至少有一个强迫邻居
c.如果父节点在斜方向(意味着这是斜向搜索),节点的水平或垂直方向上有满足条件a,b的点

举个例子:

黄色节点的父节点是在斜方向,其对应分解成向上和向右两个方向,因为在右方向发现一个蓝色跳点,因此黄色节点也应被判断为跳点
(黄色点为起点,蓝色点为跳点)


寻路流程:
1.openlist取一个权值最低的节点,然后开始搜索
2.搜索时先进行 直线搜索(上下左右四个方向搜索,直到出现跳点或者到边界),
3.再进行 斜向搜索(四个斜方向搜索,只前进一步),如果有跳点就加入openlist,知道当前方向完成搜索。
4.如果斜方向没有出现跳点或者到边界,就用进一步的斜点,在直线搜索+斜向搜索,直到所有方向都完成
5.从openlist权值最低的节点进行搜索,直到openlist为空或者找到重点


和A*相比,优缺点:
1.使用JPS算法比A更快(绝大部分地图),内存占用更小,因为openlist少了很多节点(最差的情况和A一样,最差的是每个障碍都不连续,中间都有缝隙,这样所有地方都是跳点了)
2.只适用于网格节点类型,不支持Navmesh或者路径点寻路方式

附上一张对比图:

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JPS(Jump Point Search)是一种基于A*算法寻路算法,用于寻找最短路径。它通过剪枝操作来减少搜索节点的数量,从而提高搜索效率。下面是使用C语言实现JPS寻路算法的一般步骤: 1. 定义节点结构体Node,包括坐标、距离和父节点等属性。 2. 定义地图数组,用于表示可通过和不可通过的区域。0表示可通过,1表示不可通过。 3. 实现启发式函数,用于估计从当前节点到目标节点的距离。 4. 实现检测节点是否在地图范围内的函数。 5. 实现检测节点是否可以跳跃的函数。通过观察判断节点的相邻节点中是否存在跳跃点。 6. 实现生成可跳跃点的函数。先找到当前节点的有效相邻节点,然后根据具体情况判断并返回可跳跃的节点。 7. 实现JPS算法的主函数。使用一个优先队列来存储待搜索的节点,初始化起点并将其添加到队列中。不断从队列中取出节点,检测相邻节点是否为目标节点,如果是则返回最短路径;否则,根据已知信息进行推导,生成可跳跃点并将其添加到队列中。 8. 实现回溯函数,用于从目标节点开始通过父节点信息回溯生成最短路径。 除了上述步骤外,还可以进行一些优化,如使用位运算代替乘除、设置限制条件避免重复计算等,以提高算法的执行效率。 以上是一个简要的JPS寻路算法的C语言实现步骤,具体实现还需根据具体场景和需求进行调整和完善。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值