一文弄懂基于图搜索的路径规划算法JPS(有python代码)

news2025/5/25 6:20:50

基于图搜索路径规划-JPS
关注晓理紫并回复jps获取代码
[晓理紫]

1、 Jump Point Search(跳点搜索)

核心:寻找到规划中的对称性 Path 并打破他们,从而避免扩展大量无用节点。

A*搜索的节点JPS 搜索的节点
在这里插入图片描述
在这里插入图片描述

1.1 概念

  • 强迫邻居

    • 节点 x 的 8 个邻居中有障碍,且 x 的父节点 p 经过 x 到达 n 的距离代价比不经过 x 到达的 n 的任意路径的距离代价小,则称 n 是 x 的强迫邻居。(直观来说,实际就是因为前进方向(父节点到 x 节点的方向为前进方向)的某一边的靠后位置有障碍物,因此想要到该边靠前的空位有最短的路径,就必须得经过过 x 节点。)
直线强迫邻居(红圈)对角线强迫邻居(红圈)
在这里插入图片描述
在这里插入图片描述
  • 邻居修剪

    • 如果其他节点可以通过 x 的父节点直接到达,并且路径的代价小于通过 x 到达的路径代价则没有必要通过 x 进行到达。对于 x 来说这些邻居是不需要的。:4->2 代价是根号 2,4->x->2 的代价是 2.

在这里插入图片描述

灰色节点:较差的邻居,当去它们时,没有 𝑥 的路径更便宜。 丢弃。

白色节点:自然邻居。当扩展搜索时,我们只需要考虑自然邻居。

  • 跳点

    • 如果点 y 是起点或目标点,则 y 是跳点
    • 如果 y 有邻居且是强迫邻居则 y 是跳点, 从上文强迫邻居的定义来看 neighbor 是强迫邻居,current 是跳点,二者的关系是伴生的
    • 如果 父节点到 y 是对角线移动,并且 y 经过水平或垂直方向移动可以到达跳点,则 y 是跳点。

下图举个例子,由于黄色节点的父节点是在斜方向,其对应分解成向上和向右两个方向,因为在右方向发现一个蓝色跳点,需要通过黄色节点到达跳跃点,因此黄色节点也应被判断为跳点:

在这里插入图片描述

1.2 实现原理

JPS 算法和 A* 算法非常相似,步骤大概如下:

1、openlist取一个权值最低的节点,然后开始搜索。(这些和A*是一样的)
2、搜索时,先进行 直线搜索(4个方向,跳跃搜索),然后再 斜向搜索(4个方向,只搜索一步)。如果期间某个方向搜索到跳点或者碰到障碍(或边界),则当前方向完成搜索,若有搜到跳点就添加进openlist。

# 跳跃搜索是指沿直线方向一直搜下去(可能会搜到很多格),直到搜到跳点或者障碍(边界)。一开始从起点搜索,会有4个直线方向(上下左右),要是4个斜方向都前进了一步,此时直线方向会有8个。

3、若斜方向没完成搜索,则斜方向前进一步,重复上述过程。

# 因为直线方向是跳跃式搜索,所以总是能完成搜索。

4、若所有方向已完成搜索,则认为当前节点搜索完毕,将当前节点移除于openlist,加入closelist。
5、重复取openlist权值最低节点搜索,直到openlist为空或者找到终点。

下面结合图片更好说明过程 2 和 3:首先我们从 openlist 取出绿色的节点,作为搜索的开始,先进行上方向,右方向的直线搜索,再斜向搜索,没有找到任何跳点。
在这里插入图片描述

斜方向前进一步后,在此点重复直线搜索和斜向搜索过程,仍没发现跳点。
在这里插入图片描述

斜方向前进两步后,重复直线搜索和斜向搜索过程,仍没发现跳点。
在这里插入图片描述

斜方向前进了三步后(假设当前位置为 x),在水平直线搜索上发现了一个跳点(紫色节点为强迫邻居)。

在这里插入图片描述

于是 x 也被判断为跳点,添加进 openlist。斜方向结束,绿色节点的搜索过程也就此结束,被移除于 openlist,放入 closelist。

在这里插入图片描述

1.3 代码框架

JPS 与 A*的代码框架是一样的,只是在搜索邻居时有所不同。

1、维护一个优先级队列,存放所有需要扩容的节点(OpenList)
2、所有节点的启发式函数 h(n) 都是预先定义的(可采用曼哈顿距离, 欧氏距离等)
3、优先级队列初始化为起始状态 $X_s$(OpenList.push($X_s$))
4、为图中的所有其他节点分配 g($X_s$)=0 和 g(n)=无穷大
5、循环(直到队列为空或者找到目标节点))
    如果队列为空,则返回FALSE; 返回;
    从优先级队列中删除 f(n)=g(n)+h(n) #最低的节点“n”(h(0)==0时是Dijkstra算法,g(n)==0时是贪心算法)
    将节点“n”标记为已展开  #将n加入ClosedList中
    对于节点“n”的所有未扩展邻居“m”
      如果 g(m) = 无穷大  #说明未扩展
        g(m)= g(n) + Cnm  #(从起点到n节点的代价g(n)+从n节点到m节点的代价)
        将节点“m”推入队列  #OpenList.push(m)
      如果 g(m) > g(n) + Cnm
        g(m)= g(n) + Cnm   #说明已经访问过,只修改g值不加入openList中

6、结束循环

1.4、示例过程

1、假设起点为绿色节点,终点为红色节点。
在这里插入图片描述

2、重复直线搜索和斜向搜索过程,斜方向前进了 3 步。在第 3 步判断出黄色节点为跳点(依据是水平方向有其它跳点),将黄色跳点放入 openlist,然后斜方向搜索完成,绿色节点移除于 openlist,放入 closelist。

在这里插入图片描述

3、对 openlist 下一个权值最低的节点(即黄色节点)开启搜索,在直线方向上发现了蓝色节点为跳点(依据是紫色节点为强迫邻居),类似地,放入 openlist。

在这里插入图片描述

4、由于斜方向还没结束,继续前进一步。最后一次直线搜索和斜向搜索都碰到了边界,因此黄色节点搜索完成,移除于 openlist,放入 closelist

在这里插入图片描述

5、对 openlist 下一个权值最低的节点(原为蓝色节点,下图变为黄色节点)开启搜索,直线搜索碰到边界,斜向搜索无果。斜方继续前进一步,仍然直线搜索碰到边界,斜向搜索无果

在这里插入图片描述

6、由于斜方向还没结束,继续前进一步

在这里插入图片描述

7、最终在直线方向上发现了红色节点为跳点,因此蓝色节点先被判断为跳点,只添加蓝色节点进 openlist。斜方向完成,黄色节点搜索完成。

在这里插入图片描述

8、最后 openlist 取出的蓝色节点开启搜索,在水平方向上发现红色节点,判断为终点,算法完成。

注意点:JPS 在复杂环境下要比 A*快很多,但是但机器人视角较小的情况下性能会下降不一定会比 A*要快,而且只针对网格地图的寻路,非常适合作为于 2D 网格地图型寻路手段。

2、JPS+(Jump Point Search Plus)

JPS+ 是在 JPS 寻路基础之上加上了预处理来改进,从而使寻路更加快速。

2.1、预处理

先对地图每个节点进行跳点判断,找出所有主要跳点:

在这里插入图片描述

然后对每个节点进行跳点的直线可达性判断,并记录好跳点直线可达性

在这里插入图片描述

若可达还需记录号跳点直线距离

在这里插入图片描述

类似地,对每个节点进行跳点斜向距离的记录

在这里插入图片描述

剩余各个方向如果不可到达跳点的数据记为 0 或负数距离。如果在对应的方向上移动 1 步后碰到障碍(或边界)则记为 0,如果移动 n+1 步后会碰到障碍(或边界)的数据记为负数距离-n

最后每个节点的 8 个方向都记录完毕,便完成了 JPS+的预处理过程

在这里插入图片描述

2.2、示例过程

做好了地图的预处理之后,就可以使用 JPS+算法了。大致思路与 JPS 算法相同,不过这次有了预处理的数据,可以更快的进行直线搜索和斜向搜索。

在某个搜索方向上有:

  • 对于正数距离 n(意味着距离跳点 n 格),我们可以直接将 n 步远的节点作为跳点添加进 openlist

  • 对于 0 距离(意味着一步都不可移动),我们无需在该方向搜索;

  • 对于负数距离 -n(意味着距离边界或障碍 n 格),我们直接将 n 步远的节点进行一次跳点判断(有可能满足跳点的第三条件,不过得益于预处理的数据,这步也可以很快完成)。

如下图示,起始节点通过已记录的向上距离,直接将 3 步远的跳点添加进 openlist,而不再像以前需要迭代三步(还每步都要判断是否跳点)

在这里插入图片描述

其它过程也是类似的:

在这里插入图片描述

在这里插入图片描述

2.3, 总结

可以看到 JPS/JPS+ 算法里只有跳点才会被加入 openlist 里,排除了大量不必要的点,最后找出来的最短路径也是由跳点组成。这也是 JPS/JPS+ 高效的主要原因。

  • JPS :

    • 绝大部分地图,使用 JPS 算法都会比 A* 算法更快,内存占用也更小(openlist 里节点少了很多)。

    • JPS 在跳点判断上,要尽可能避免递归的深度过大(或者期待一下以后出现避免递归的算法),否则在超大型的地图里递归判断跳点可能会造成灾难。

    • JPS 也可以用于动态变化的地图,只是每次地图改变都需要再进行一次 JPS 搜索。

    • JPS 天生拥有合并节点(亦或者说是在一条直线里移除中间不必要节点)的功能,但是仍存在一些可以继续合并的地方。

    • JPS 只适用于 网格(grid)节点类型,不支持 Navmesh 或者路径点(Way Point)。

  • JPS+ :

    • JPS+ 相比 JPS 算法又是更快上一个档次(特别是避免了过多层递归判断跳点),内存占用则是每个格子需要额外记录 8 个方向的距离数据。

    • JPS+ 算法由于包含预处理过程,这让它面对动态变化的地图有天生的劣势(几乎是不可以接受动态地图的),因此更适合用于静态地图。

    • JPS+ 预处理的复杂度为 O(n),n 代表地图格子数。

对比:

DijkstraA*JPS
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3 代码获取方式

关注晓理紫并回复有jps获取代码

{晓理紫|小李子}喜分享,也很需要你的支持,喜欢留下痕迹哦!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1010584.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【深度学习】 Python 和 NumPy 系列教程(十八):Matplotlib详解:2、3d绘图类型(4)3D曲面图(3D Surface Plot)

目录 一、前言 二、实验环境 三、Matplotlib详解 1、2d绘图类型 2、3d绘图类型 0. 设置中文字体 1. 3D线框图(3D Line Plot) 2. 3D散点图(3D Scatter Plot) 3. 3D条形图(3D Bar Plot) 4. 3D曲面图…

Copymonkey:AI生成营销广告文案

【产品介绍】 CopyMonkey.ai 是一家成立于2021年的创新型人工智能(AI)初创企业,专注于开发一款强大的AI写作助手。我们的产品旨在帮助用户以更高效且更自然的方式创作各种文本内容,无论是文章、博客、电子邮件、简历还是其他类型的…

ARM核心时间线

指令集架构处理器家族(ARM RISC)ARMv1ARM1ARMv2ARM2、ARM3ARMv3ARM6、ARM7ARMv4StrongARM、ARM7TDMI、ARM9TDMIARMv5ARM7EJ、ARM9E、ARM10E、XScaleARMv6ARM11、ARM Cortex-MARMv7ARM Cortex-A、ARM Cortex-M、ARM Cortex-RARMv8-A armv8.2Cortex-A35、Cortex-A50系列[18]、Cor…

华为云云耀云服务器L实例评测|在Docker环境下部署ZPan个人网盘系统

华为云云耀云服务器L实例评测|在Docker环境下部署ZPan个人网盘系统 一、云耀云服务器L实例介绍1.1 云耀云服务器L实例简介1.2 云耀云服务器L实例特点 二、ZPan介绍2.1 ZPan简介2.2 ZPan特点 三、华为对象存储服务OBS介绍3.1 华为OBS介绍3.2 华为OBS应用场景 四、本次…

部分依赖图(Partial Dependence Plots)以及实战-疾病引起原因解释

接上篇,特征重要性解释 特征重要性展示了每个特征发挥的作用情况,partial dependence plots可以展示一个特征怎样影响的了预测结果。 前提同样是应用在模型建立完成后进行使用,概述如下: 首先选中一个样本数据,此时想…

企业级镜像仓库Harbor的安装与配置

企业级镜像仓库Harbor的安装与配置 HarborHarbor概述安装Harbor配置 Harbor运行安装程序脚本登录启动与停止Harbor 登录Harbor仓库登录异常解决方案登录退出 推送拉取Harbor镜像镜像命名规范创建项目推送镜像拉取镜像 Harbor Harbor概述 Harbor是一个开源的容器镜像仓库管理系…

零售超市如何应对消费者需求?非常全面!

随着科技的飞速发展和消费者期望的不断演变,零售行业正经历着一场深刻的革命。传统零售模式逐渐被新零售模式所取代,而其中一个备受关注的元素是自动售货机。 自动售货机不仅在商场、车站和办公楼等高流量地点迅速扩张,还在重新定义我们如何购…

日志平台搭建第七章:Linux安装kafka-manager

相关链接https://github.com/yahoo/kafka-manager/releases kafka-manager-2.0.0.2下载地址 百度云链接:https://pan.baidu.com/s/1XinGcwpXU9YBF46qkrKS_A 提取码:tzvg 一、安装部署 1.把kafka-manager-2.0.0.2.zip拷贝到目录 /opt/app/elk 2.解压…

VSD Viewer 6.16.1(Visio绘图文件阅读器)

VSD Viewer是一款用于查看和打开Microsoft Visio文件的应用程序。Visio是一种流程图和图表设计工具,常用于创建各种类型的图形和图表,如组织结构图、流程图、网络拓扑图等。 VSD Viewer允许用户在没有安装Visio软件的情况下浏览和查看Visio文件。它提供…

变频器频率传感器信号转电压或电流信号隔离变送器0-1KHz / 0-5KHz / 0-10KHz转0-5V/0-10V/0-10mA/4-20mA

主要特性 精度等级&#xff1a;0.2 级全量程内极高的线性度&#xff08;非线性度<0.1%&#xff09;辅助电源/信号输入/信号输出&#xff1a; 2500VDC 三隔离辅助电源&#xff1a;5VDC&#xff0c;12VDC&#xff0c;24VDC 等单电源供电输入频率信号&#xff1a;0-1KHz / 0-5…

openGauss学习笔记-69 openGauss 数据库管理-创建和管理普通表-更新表中数据

文章目录 openGauss学习笔记-69 openGauss 数据库管理-创建和管理普通表-更新表中数据 openGauss学习笔记-69 openGauss 数据库管理-创建和管理普通表-更新表中数据 修改已经存储在数据库中数据的行为叫做更新。用户可以更新单独一行、所有行或者指定的部分行。还可以独立更新…

C++(Qt)软件调试---GCC编译参数学习-程序检测(13)

C(Qt)软件调试—GCC编译参数学习-程序检测&#xff08;13&#xff09; 文章目录 C(Qt)软件调试---GCC编译参数学习-程序检测&#xff08;13&#xff09;1、前言1.1 概述1.2 测试环境 2、GCC编译警告选项1.1 编译警告的作用1.2 GCC常用的编译警告选项 3、GCC程序检测选项1.1 性能…

解决Agora声网音视频在后台没有声音的问题

前言:本文会介绍 Android 与 iOS 两个平台的处理方式 一、Android高版本在应用退到后台时,系统为了省电会限制应用的后台活动,因此我们需要开启一个前台服务,在前台服务中发送常驻任务栏通知,以此来保证App 退到后台时不会被限制活动. 前台服务代码如下: package com.notify…

在ubuntu安装vncserver,可以打开远程桌面

1.网上查找vncserver的资料 2.在ubuntu20.04上面使用 https://www.5axxw.com/questions/simple/ywnpl5 参考了这个和其他很多 我直接运行vncserver&#xff0c;没有成功&#xff01; 当我使用这个命令时 xtigervncviewer -SecurityTypes VncAuth -passwd /home/yx/.vnc/passw…

构建高效的接口自动化测试框架思路

在选择接口测试自动化框架时&#xff0c;需要根据团队的技术栈和项目需求来综合考虑。对于测试团队来说&#xff0c;使用Python相关的测试框架更为便捷。无论选择哪种框架&#xff0c;重要的是确保 框架功能完备&#xff0c;易于维护和扩展&#xff0c;提高测试效率和准确性。今…

Biome-BGC生态系统模型与Python融合技术教程

详情点击公众号链接&#xff1a;Biome-BGC生态系统模型与Python融合技术教程 前言 Biome-BGC是利用站点描述数据、气象数据和植被生理生态参数&#xff0c;模拟日尺度碳、水和氮通量的有效模型&#xff0c;其研究的空间尺度可以从点尺度扩展到陆地生态系统。 在Biome-BGC模型…

crm、scrm、ocrm、acrm、ccrm等等分别是什么?有什么区别?

crm、SCRM、OCRM、ACRM、CCRM等等分别是什么&#xff1f;crm&#xff0c;scrm&#xff0c;ocrm&#xff0c;acrm&#xff0c;ccrm有什么区别&#xff1f;又有什么联系&#xff1f;这些系统各自之间都有哪些优势和缺点呢&#xff1f;今天将带领大家深入浅出的系统了解crm&#x…

idea 创建java web项目 run后出现404现象

1、创建新项目 创建的新项目只是单纯的java项目&#xff0c;如图 2、添加lib库文件&#xff0c;里面存放jar包&#xff0c;并导入库配置 这里要注意&#xff0c;需要先添加lib库文件再去配置模块和工件否则会出现404现象 3、打开模块设置&#xff0c;设置项目配置 将本…

c语言练习58:⾃定义类型:结构体

⾃定义类型&#xff1a;结构体 结构体的概念 结构是⼀些值的集合&#xff0c;这些值称为成员变量。结构的每个成员可以是不同类型的变量。 结构体是一个种自定义的数据类型&#xff0c;它可以由很多个默认数据类型组成。它主要用于描述复杂场景下的变量。 例如&#xff0c;想…

go语言基础--杂谈

常量运行期间&#xff0c;不可以改变的值 const PI float64 3.14字面常量 所谓字面常量&#xff0c;是值程序中硬编码的常量 123 //整型类型常量 156.78 //浮点类型的常量 true //布尔类型的常量 “abc”//字符串类型的常量//const PI float64 3.14 const PI 3.14 // //P…