1.基于搜索的路径规划:BFS、DFS、Dijkstra、A*、JPS
1.概览
可以对比不同算法的小动画 PathFinding.js (qiao.github.io)
- 工作空间规划
- 机器人有不同的形状和大小
- 碰撞检测需要了解机器人的几何形状,耗时且难度大
- 我们希望将机器人表示为点,只需要把工作空间转换为配置空间C-obstacle,将原始的空间膨胀,这是一次性的
- C-space R3空间
- C-obstacle 膨胀后的障碍空障碍
- C-space = C-obstacle ∪ C-free

- 图搜索算法的逻辑总是在这个框架下
- 维护一个容器,该容器记录所有准备去访问的节点,同时一个有一个容器记录了所有已经访问的节点,避免形成环
- 这个容器刚开始是空的,我们初始化放入起始节点
- Loop
- 访问一个节点:在容器里根据一种指标弹出一个节点
- 扩展:发现该节点所有可能的邻居节点
- 插入:将这些邻居节点插入到容器中
- End Loop
- 容器已经全空就达到了终止条件
2.BFS和DFS
广度优先搜索和深度优先搜索

- 深度优先算法:总是移除容器中最深层的节点(总是把尝试一直把一条路走到底)
- 首先S进入栈
- S出栈,发现S的周围元素 d e p,S的周围元素 d e p 进入栈
- d出栈,发现d的周围元素 b c e,d的周围元素 b c e 进入栈

- 广度优先算法:总是移除容器中最浅层的节点(一层一层的搜索)
- S 进入队列
- S 弹出队列,发现S的周围元素 d e p,S的周围元素 d e p 进入队列
- p 弹出队列,发现p的周围元素 q,p的周围元素 q 进入队列

- 两种算法DFS总是一条路走到黑,所以它找到的路径不是最短路径

3.贪心算法
- DFS或者BFS是通过先入或后入来判定从容器中拿出哪个节点
- 贪心算法是一种启发式搜索,通过认为定义的”最短“判定从容器中弹出哪个节点(不一定有全局最优解)

4.Dijkstra算法
DFS和BFS都没有考虑边的代价问题,Dijkstra算法如果不考虑边的代价实际上就退化成广度优先算法
- g(n):从起始节点到当前节点n累计的最佳成本
- 更新节点n相邻节点的代价(有可能当前节点n使得它周围的节点m代价降低)
- 保证已扩展/访问的节点开销最小
以下图为例跑一遍流程
- S弹出队列,发现S周围节点 d e p,S的周围节点根据代价排序进入优先级队列 p d e
- p弹出队列,发现p周围节点 q,q的周围节点 q 进入优先级队列
- e弹出队列,发现e周围节点 h r,e的周围节点根据代价排序进入优先级队列 r h

算法伪代码逻辑
- 维护priority queue存储所有已访问的节点
- 将初始节点Xs加入到队列
- 标记 g(Xs)=0,其余的节点代价为无穷大
- Loop
- if the queue is empty, return FALSE; break;
- Remove the node "n" with the lowest g(n) from the priority queue
- mark node "n" as expanded
- if the node "n" is the goal state, return TRUE; break;
- For all unexpanded neighbors "m" of node "n"
- if g(m) = infinite
- if g(m) = g(n) + COSTnm
- push node "m" into queue
- if g(m) > g(n) + COSTnm
- g(m) = g(n) + COSTnm
- if g(m) = infinite
- End Loop
5.A*算法
- 对Dijkstra算法进行优化,加上贪心算法的思想就可以得到A*算法
- h(n):从当前节点n到目标状态的估计最小代价(即目标代价)
- g(n):从起始节点到当前节点n累计的最佳成本
- Weighted A*:f(n):g(n)+εh(n), ε>1:经过节点n,从起始节点到目标节点估计的最小代价
- 如果代价估计大于实际代价,最终找到的路径也不一定是最优路径。ε越大越接近于贪心算法,ε=1就是A*算法,ε=0就是Dijkstra算法
- 算法逻辑与Dijkstra完全相同,但排序将g(n)修改为f(n)
- 以下图为例解释,每个节点的估计代价h已经给出
- 弹出S节点,发现S周围节点a,将a加入优先队列
- 弹出a节点,发现a周围节点b d e,通过计算当前代价和估计代价得到应该按照 d e b 加入优先队列

6.A*算法的优化
6.1 The Best Heuristic
为了得到最优解,我们必须满足估计最小代价和实际最小代价的关系为h(n)≤h*(n),但是如果h(n)远远小于真实最小代价的话,就会导致右图所示的情况,进行很多无效的搜索,因为更小的h(n)使得算法误以为会有一条更有的路径
但实际上这种规格化的网格只能水平走或斜45度走。所以这里不使用欧氏距离,而是使用更标准的算法会更快速的找到目标

6.2 Tie Breaker
因为路径中大量对称的点都会有相同的F(n)值,这些值都需要不断的去遍历进行搜索,这会导致它搜索很多无效的点
核心思想:想办法打破这种平衡,比如计算一个常数p让每个点的F(n)值不太相同
具体做法为F(n) = g(n) + h(n)*(1+p) ,不过这种做法也可能使得h(n)>h*(n),使得我们估计最小代价大于实际最小代价,无法找到最优解

也可以如果有相同的f(n),则我们选取更小的h(n)值弹出容器
或者是我们添加一种倾向性,让他倾向于去行走一条直线,在无障碍的情况下是很好的,但是有障碍的情况下缺不太符合人的直观体会

7. Jump Point Search
先看一下JPS算法和A*算法搜索过程的对比

JPS算法思想1:Look Ahead Rule
- 劣质邻居(inferior neighbors)灰色节点:到达这些节点时,没有x节点的路径更优
- 父节点为4时,如果此时由x到1,它的消耗是4->x->1,不如x->1
- 父节点为4时,如果此时由x到2,它的消耗是4->x->2,不如4->2
- 父节点为4时,如果此时由x到3,它的消耗是4->x->3,和4->2->3相同,经过x的路径没有更优
- 自然邻居(natural neighbors)白色节点:我们只需要考虑通过白色节点
- 强制邻居(Forced Neighbors)黑色节点:墙
JSP算法思想2:Jumping Rules
- 直线规则:如果周围没有障碍物,就是Look Ahead Rule情况1,它只需要继续走直线
- 当他走到y节点时,是Look Ahead Rule情况3
- 对角线规则:如果周围没有障碍物,就是Look Ahead Rule情况2,它可以选择三条路线,优先选择水平,然后选择垂直,最后选择对角线运动。






1.基于搜索的路径规划:BFS、DFS、Dijkstra、A*、JPS的更多相关文章
- iOS高德地图使用-搜索,路径规划
项目中想加入地图功能,使用高德地图第三方,想要实现确定一个位置,搜索路线并且显示的方法.耗了一番功夫,总算实现了. 效果 WeChat_1462507820.jpeg 一.配置工作 1.申请key 访 ...
- 基于pgrouting的路径规划处理
对于GIS业务来说,路径规划是非常基础的一个业务,一般公司如果处理,都会直接选择调用已经成熟的第三方的接口,比如高德.百度等.当然其实路径规划的算法非常多,像比较著名的Dijkstra.A*算法等.当 ...
- 【BZOJ-3627】路径规划 分层图 + Dijkstra + spfa
3627: [JLOI2014]路径规划 Time Limit: 30 Sec Memory Limit: 128 MBSubmit: 186 Solved: 70[Submit][Status] ...
- 基于Arcgis Engine 10.2(C#)+PostgreSQL 11(Postgis 3)+pgRouting 3.0实现使用数据库进行路径规划
前言:最近在(被迫)使用ArcGIS Engine10.2(.NET平台)进行二次开发(桌面应用),因为想做一个最短路径查询的功能,而arcgis的网络分析又比较麻烦,于是想到了使用Postgis.但 ...
- 机器人路径规划其一 Dijkstra Algorithm【附动态图源码】
首先要说明的是,机器人路径规划与轨迹规划属于两个不同的概念,一般而言,轨迹规划针对的对象为机器人末端坐标系或者某个关节的位置速度加速度在时域的规划,常用的方法为多项式样条插值,梯形轨迹等等,而路径规划 ...
- 机器人路径规划其二 A-Star Algorithm【附动态图源码】
首先要说明的是,机器人路径规划与轨迹规划属于两个不同的概念,一般而言,轨迹规划针对的对象为机器人末端坐标系或者某个关节的位置速度加速度在时域的规划,常用的方法为多项式样条插值,梯形轨迹等等,而路径规划 ...
- [python] A*算法基于栅格地图的全局路径规划
# 所有节点的g值并没有初始化为无穷大 # 当两个子节点的f值一样时,程序选择最先搜索到的一个作为父节点加入closed # 对相同数值的不同对待,导致不同版本的A*算法找到等长的不同路径 # 最后c ...
- 基于谷歌地图的Dijkstra算法水路路径规划
最终效果图如下: 还是图.邻接表,可以模拟出几个对象=>节点.边.路径.三个类分别如下: Node 节点: using System; using System.Collections.Gene ...
- python实现基于百度路径规划接口的坐标对获取两点驾车距离的计算
今天为大家介绍一种通过python实现坐标对间距离数据的获取方法.接口采用百度开发的路径规划接口. 1.调用接口: 接口:(传入起点坐标串,结束坐标串:ak值需要注册百度开发者) 接口详细说明 htt ...
- 游戏AI之路径规划(3)
目录 使用路径点(Way Point)作为节点 洪水填充算法创建路径点 使用导航网(Navigation Mesh)作为节点 区域分割 预计算 路径查询表 路径成本查询表 寻路的改进 平均帧运算 路径 ...
随机推荐
- f-string 高效的字符串格式化
f-string,称为格式化字符串常量(formatted string literals),是Python3.6新引入的一种字符串格式化方法,该方法源于PEP 498 – Literal Strin ...
- web29~web39
参考博客: https://blog.csdn.net/m0_62422842/article/details/125507970 https://www.cnblogs.com/amazingman ...
- RBMQ与odoo15的集成
背景:在对接物联网设备时候常用的协议就是:MQTT.AMQ.https.还有WebSocket,此案例就是针对接物联网设备传输的消息的消费 原理:通过新建守护线程的方式来启动mq服务,来消费设备平台端 ...
- 在 Mac 系统上使用 docker
1.通过 brew 安装 docker client brew install docker 2.通过 brew 安装 colima(开源的轻量级容器,可以在 linux 和 mac 上运行) bre ...
- Qt 图片轮播
最近研究了一下图片轮播,主要是用到了QPropertyAnimation这个类,具体代码示例如下: main.cpp #include <QApplication> #include &q ...
- MVVM - Model和ViewModel的创建和配置
MVVM-Model和ViewModel的创建和配置 本文同时为b站WPF课程的笔记,相关示例代码 简介 MVVM:Model-View-ViewModel,是一种软件架构的模式.通过引入一个中间层V ...
- 函数使用十二:BAPI_CONTRACT_CREATE
*&---------------------------------------------------------------------* *& Report ZBAPI_WB2 ...
- 鸿蒙运动项目开发:封装超级好用的 RCP 网络库(中)—— 错误处理,会话管理与网络状态检测篇
鸿蒙核心技术##运动开发## Remote Communication Kit(远场通信服务) 在上篇中,我们介绍了 RCP 网络库的核心功能,包括请求参数的封装.响应内容的转换以及拦截器与日志记录机 ...
- 技术干货 |看我如何来解Web Terminal假性输入框
编者按 写在前面的话 在介绍本篇文章的时候,先说一下本篇文章的一些背景.笔者是基于公司的基础建设哆啦 A 梦(Doraemon) (https://github.com/DTStack/doraemo ...
- 11-2 MySQL 数据库对象编写建议(参考)
11-2 MySQL 数据库对象编写建议(参考) @ 目录 11-2 MySQL 数据库对象编写建议(参考) 1. 数据库对象编写建议/推荐 1.1 关于库 1.2 关于表.列 1.3 索引 1.4 ...