位置: IT常识 - 正文

路径规划 | 图解A*、Dijkstra、GBFS算法的异同(附C++/Python/Matlab仿真)(路径规划是什么意思)

编辑:rootadmin
路径规划 | 图解A*、Dijkstra、GBFS算法的异同(附C++/Python/Matlab仿真) 目录0 专栏介绍1 栅格地图与邻域2 贪婪最佳优先搜索3 Dijkstra算法4 启发式A*搜索5 A*、Dijkstra、GBFS算法的异同6 算法仿真与实现6.1 算法流程6.2 ROS C++实现6.3 Python实现6.4 Matlab实现0 专栏介绍

推荐整理分享路径规划 | 图解A*、Dijkstra、GBFS算法的异同(附C++/Python/Matlab仿真)(路径规划是什么意思),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:路径规划最新算法,路径规划最新算法,路径规划图片,路径规划教程,路径规划的基本流程和方法,路径规划的基本流程和方法,路径规划定义,路径规划是什么意思,内容如对您有帮助,希望把文章链接给更多的朋友!

🔥附C++/Python/Matlab全套代码🔥课程设计、毕业设计、创新竞赛必备!详细介绍全局规划(图搜索、采样法、智能算法等);局部规划(DWA、APF等);曲线优化(贝塞尔曲线、B样条曲线等)。

🚀详情:图解自动驾驶中的运动规划(Motion Planning),附几十种规划算法


1 栅格地图与邻域

搜索(Search)是指从初始状态(节点)出发寻找一组能达到目标的行动序列(或称问题的解)的过程。

在图搜索中,往往将环境简化为栅格地图(Grid Map),易于刻画固定场景,同时也便于计算机控制系统进行信息处理。所谓栅格就是将连续地图用固定大小正方形方格进行离散化的单位。

在栅格地图中,常见的邻域(neighbor)模式如下所示,即

8邻域24邻域48邻域

栅格的邻域表示了从当前位置出发下一次搜索的集合,例如八邻域法中,当前栅格只能和周围的八个栅格相连形成局部路径。

下面是一个图搜索问题的例子,可以直观理解什么是搜索问题。

例1:在如下的栅格地图中,设绿色栅格为起点,红色栅格为终点,灰色栅格为障碍,白色栅格为可行点,问如何设计一条由栅格组成的连接起点、终点的路径,并尽可能使路径最短?

接下来,围绕这个问题展开阐述。

2 贪婪最佳优先搜索

一个朴素的想法是:每一次搜索时就找那些与终点最近的节点,这里衡量最近可以用多种度量方式——曼哈顿距离、欧式距离等。这种方法像一头狼贪婪地望着食物,迫切寻求最近的路径,因此称为贪婪最佳优先搜索(Greedy Best First Search, GBFS)。

假设采用八邻域法,在GBFS思想指导下,在起点的八邻域中就会选择最右侧的节点,如下所示。

循环地,直到如下所示的节点,因为邻域内有障碍,这些障碍节点不会被候选,所以此时离终点最近的就是下方的方格

依次类推直至终点

3 Dijkstra算法路径规划 | 图解A*、Dijkstra、GBFS算法的异同(附C++/Python/Matlab仿真)(路径规划是什么意思)

Dijkstra算法走向了另一个极端,它完全不考虑扩展节点与终点的关系,而是定义了一个路径耗散函数g(n)g(n)g(n),从起点开始,机器人每走一个栅格就会产生一定的代价或耗散,因为Dijkstra算法希望路径最短,所以每次首选那些使路径耗散最小的节点。

依照Dijkstra算法的观点,从起点开始,其八个邻域节点都会被依次探索,因为它们离起点最近,接着再探索这些节点的子节点。

因此Dijkstra算法会遍历大量的节点,一圈圈地逼近终点

4 启发式A*搜索

A*算法是非常有效且常用的路径规划算法之一,其是结合Dijsktra算法与GBFS各自优势的启发式搜索算法,其搜索代价评估函数为

f(n)=g(n)+h(n)f(n)=g(n)+h(n)f(n)=g(n)+h(n)

其中g(n)g(n)g(n)代表路径耗散,是Dijsktra算法分量;h(n)h(n)h(n)代表下一个搜索节点与终点的距离,启发式地引导机器人朝着终点拓展,是GBFS算法分量。

兼具两个算法特点的A*算法既保持完备性,又在一定条件下体现出最优性,被广泛应用于路径规划中。

5 A*、Dijkstra、GBFS算法的异同

特别地

当g(n)=g\left( n \right) =0g(n)=0时,启发函数影响占据主导,A*算法退化为GBFS算法——完全不考虑状态空间本身的固有属性,不择手段地追求对目标的趋近,此时算法搜索效率将得到提升,但最优性无法保证;当h(n)=h(n)=0h(n)=0时,路径耗散函数影响占据主导,A*算法退化为Dijsktra算法——无先验信息搜索,此时算法搜索效率下降,但最优性上升。

三个算法的直观比较如下所示

6 算法仿真与实现6.1 算法流程

6.2 ROS C++实现

核心代码如下

std::tuple<bool, std::vector<Node>> AStar::plan(const unsigned char* costs, const Node& start, const Node& goal, std::vector<Node> &expand) { // open list std::priority_queue<Node, std::vector<Node>, compare_cost> open_list; open_list.push(start); // closed list std::unordered_set<Node, NodeIdAsHash, compare_coordinates> closed_list; // expand list expand.clear(); expand.push_back(start); // get all possible motions const std::vector<Node> motion = getMotion(); // main loop while (!open_list.empty()) { // pop current node from open list Node current = open_list.top(); open_list.pop(); current.id = this->grid2Index(current.x, current.y); // current node do not exist in closed list if (closed_list.find(current) != closed_list.end()) continue; // goal found if (current==goal) { closed_list.insert(current); return {true, this->_convertClosedListToPath(closed_list, start, goal)}; } // explore neighbor of current node for (const auto& m : motion) { Node new_point = current + m; // current node do not exist in closed list if (closed_list.find(new_point) != closed_list.end()) continue; // explore a new node new_point.id = this->grid2Index(new_point.x, new_point.y); new_point.pid = current.id; // if using dijkstra implementation, do not consider heuristics cost if(!this->is_dijkstra_) new_point.h_cost = std::sqrt(std::pow(new_point.x - goal.x, 2) + std::pow(new_point.y - goal.y, 2)); // if using GBFS implementation, only consider heuristics cost if(this->is_gbfs_) new_point.cost = 0; // goal found if (new_point==goal) { open_list.push(new_point); break; } // bext node hit the boundary or obstacle if (new_point.id < 0 || new_point.id >= this->ns_ || costs[new_point.id] >= this->lethal_cost_ * this->factor_) continue; open_list.push(new_point); expand.push_back(new_point); } closed_list.insert(current); } return {false, {}}; }}

6.3 Python实现

核心代码如下

def plan(self): # OPEN set with priority and CLOSED set OPEN = [] heapq.heappush(OPEN, self.start) CLOSED = [] while OPEN: node = heapq.heappop(OPEN) # exists in CLOSED set if node in CLOSED: continue # goal found if node == self.goal: CLOSED.append(node) return self.extractPath(CLOSED), CLOSED for node_n in self.getNeighbor(node): # exists in CLOSED set if node_n in CLOSED: continue node_n.parent = node.current node_n.h = self.h(node_n, self.goal) # goal found if node_n == self.goal: heapq.heappush(OPEN, node_n) break # update OPEN set heapq.heappush(OPEN, node_n) CLOSED.append(node) return [], []

6.4 Matlab实现

核心代码如下

while ~isempty(OPEN(:, 1)) % pop f = OPEN(:, 3) + OPEN(:, 4); [~, index] = min(f); cur_node = OPEN(index, :); OPEN(index, :) = []; % exists in CLOSED set if loc_list(cur_node, CLOSED, [1, 2]) continue end % goal found if cur_node(1) == goal(1) && cur_node(2) == goal(2) CLOSED = [cur_node; CLOSED]; flag = true; cost = cur_node(3); break end % explore neighbors for i=1:neighbor_num node_n = [cur_node(1) + neighbor(i, 1), ... cur_node(2) + neighbor(i, 2), ... cur_node(3) + neighbor(i, 3), ... 0, cur_node(1), cur_node(2) ]; node_n(4) = h(node_n(1:2), goal); % exists in CLOSED set if loc_list(cur_node, CLOSED, [1, 2]) continue end % obstacle if map(node_n(1), node_n(2)) == 2 continue; end % goal found if cur_node(1) == goal(1) && cur_node(2) == goal(2) CLOSED = [cur_node; CLOSED]; flag = true; cost = cur_node(3); break end % update expand zone expand = [expand; node_n(1:2)]; % update OPEN set OPEN = [OPEN; node_n]; end CLOSED = [cur_node; CLOSED];end


🔥 更多精彩专栏:

《ROS从入门到精通》《Pytorch深度学习实战》《机器学习强基计划》《运动规划实战精讲》…

👇源码获取 · 技术交流 · 抱团学习 · 咨询分享 请联系👇

本文链接地址:https://www.jiuchutong.com/zhishi/297662.html 转载请保留说明!

上一篇:vue3 框架学习概念笔记(vue框架总结)

下一篇:前端发起请求,后端响应请求的整个过程(前端发起请求怎么设置)

  • 精准微博加粉丝的方法及注意事项(精准微博加粉丝是真的吗)

    精准微博加粉丝的方法及注意事项(精准微博加粉丝是真的吗)

  • oppor17黑屏怎么强制重启(oppor17黑屏怎么回事)

    oppor17黑屏怎么强制重启(oppor17黑屏怎么回事)

  • 耳机插头规格有几种(耳机插头的型号)

    耳机插头规格有几种(耳机插头的型号)

  • 备忘录可以设置密码吗(备忘录可以设置背景颜色吗)

    备忘录可以设置密码吗(备忘录可以设置背景颜色吗)

  • vivos6充电慢怎么办(vivox6充电慢)

    vivos6充电慢怎么办(vivox6充电慢)

  • Word快速访问工具栏在哪里(Word快速访问工具栏怎么恢复)

    Word快速访问工具栏在哪里(Word快速访问工具栏怎么恢复)

  • 魅族17没有光学防抖吗(魅族17pro没有光学防抖影响大吗)

    魅族17没有光学防抖吗(魅族17pro没有光学防抖影响大吗)

  • 拍立得mini7c和7s区别(拍立得mini7c和mini9相纸通用吗)

    拍立得mini7c和7s区别(拍立得mini7c和mini9相纸通用吗)

  • iphone慢动作视频恢复普通(iPhone慢动作视频)

    iphone慢动作视频恢复普通(iPhone慢动作视频)

  • 苹果13.3系统耗电吗(苹果13系统费电吗)

    苹果13.3系统耗电吗(苹果13系统费电吗)

  • word怎么向下添加空白页(word文档怎么往下加行)

    word怎么向下添加空白页(word文档怎么往下加行)

  • qq扩列为什么匹配不到人(qq扩列为什么只能匹配5次)

    qq扩列为什么匹配不到人(qq扩列为什么只能匹配5次)

  • 为什么大王卡对优酷也免流(大王卡为什么不能用流量)

    为什么大王卡对优酷也免流(大王卡为什么不能用流量)

  • opporeno2网速慢怎么办(opporeno手机上网反应慢)

    opporeno2网速慢怎么办(opporeno手机上网反应慢)

  • 路由表中包含哪些核心信息(路由表中包含哪几项)

    路由表中包含哪些核心信息(路由表中包含哪几项)

  • 快手特别关注有什么功能(快手特别关注有上限吗)

    快手特别关注有什么功能(快手特别关注有上限吗)

  • 苹果手机没有原彩显示怎么回事(苹果手机没有原彩影响拍照吗)

    苹果手机没有原彩显示怎么回事(苹果手机没有原彩影响拍照吗)

  • 快手粉丝被删了怎么办(快手粉丝被删了还能恢复吗)

    快手粉丝被删了怎么办(快手粉丝被删了还能恢复吗)

  • 台式电脑卡死怎么解决(台式电脑直接卡死)

    台式电脑卡死怎么解决(台式电脑直接卡死)

  • 拼多多怎么才算新用户(拼多多怎么才算拼单成功)

    拼多多怎么才算新用户(拼多多怎么才算拼单成功)

  • 微信勿扰模式什么意思(微信勿扰模式什么效果)

    微信勿扰模式什么意思(微信勿扰模式什么效果)

  • 苹果无线耳机二代有线和无线区别(苹果无线耳机二代多少钱)

    苹果无线耳机二代有线和无线区别(苹果无线耳机二代多少钱)

  • vivoz3水滴屏什么意思(vivo水滴屏是什么意思)

    vivoz3水滴屏什么意思(vivo水滴屏是什么意思)

  • iphone8p怎么截屏(iphone8p怎么截屏快捷键)

    iphone8p怎么截屏(iphone8p怎么截屏快捷键)

  • discuz怎么添加广告位?自定义广告位方法浅析(discuz怎么用)

    discuz怎么添加广告位?自定义广告位方法浅析(discuz怎么用)

  • 税务安全组件初审流程
  • 从价税是什么意思
  • 个人所得税如何查询工资
  • 财务报表审计的标准
  • 家庭保洁服务价格表
  • 所得税费用是哪类科目
  • 税控服务费属于什么费用
  • 保险企业汇算清缴规定
  • 企业自建房屋卖给职工怎么做账务处理
  • 成本类科目期末借方余额表示
  • 业务招待费如何调增调减
  • 发工资四舍五入可以吗
  • 建筑业确认主营业务收入
  • 已注销企业可以恢复吗
  • 工会经费计入应付职工薪酬
  • 外汇收支申报流程
  • 船运费发票抵扣多少税
  • 公司纳税人是什么意思是不是法人
  • 增值税普通发票需要交税吗
  • 建安发票税率是多少2011年
  • 税局税种认定
  • 出售固定资产属于收入
  • 递延资产摊销计算公式
  • 长期待摊费用发生当月摊还是次月摊
  • 弥补以前年度亏损是什么意思
  • Secure Boot什么意思?BIOS中Secure Boot灰色无法更改解决方法详解
  • 自制原始发票
  • 立陶宛广场
  • zend框架教程
  • 银行存款缴纳房产税会计分录
  • 固定资产折旧企业所得税税前扣除标准
  • 对方不开票
  • 非同级财政拨款收入属于什么科目
  • Vue3 + Pinia 持久化存储
  • php获取开始与结束的函数
  • pinf命令
  • php不同用户登录不同页面
  • 分公司在外地,企业怎么交税
  • 税控盘费和服务费都可以减免吗
  • 帝国cms如何使用
  • 一般纳税人只有进项怎么报税
  • 劳务派遣工资是死的吗
  • 技术服务型公司如何做账务处理
  • 小规模纳税人不超过30万怎么做账
  • 《中华人民共和国禁毒法》自( )起施行
  • mysql 大量数据
  • 周转材料应该计入什么科目
  • 股东出资资本金可以是问别人借来的吗
  • 固定资产清理产生的收入计入
  • 单位给个人转款怎么做账
  • 什么是企业管理的基础工作
  • 交易的价格
  • 营业执照怎么换地址
  • MySQL中truncate误操作后的数据恢复案例
  • 总结下半年工作计划
  • mysql8高可用
  • mysql运行代码
  • windows需要更新吗?
  • server2008 无法启动
  • 无windows什么意思
  • ubuntu18.04启用root
  • win10系统光盘制作
  • win8 侧边栏
  • searchnav.exe - searchnav是什么进程 有什么用
  • bootstrap导航有哪些
  • jquery制作图片提示效果
  • ip地址一键切换
  • cmd替换文件命令
  • python多线程菜鸟教程
  • java script教程
  • Android之Service
  • Python Requests 基础入门
  • python动态加载py
  • python爬取三国演义前六章
  • Python遍历文件夹中的图片
  • 增值税纳税申报时间
  • 重庆车牌号申请
  • 江苏电子税务局电话
  • 地税是什么时候开始征收耕地的呢
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设