DFS和BFS

说迪杰斯特拉算法之前,先为大家简单介绍两种常见的图论搜索算法,深度优先(DFS),广度优先(BFS)。

深度优先

  1. 深度优先就是从根节点开始,找到它的第一个子节点
  2. 在找到第一个子节点的子节点,依次往下递推直到当前节点没有其他的子节点
  3. 返回当前子节点的父节点,寻找有没有另外的子节点,若没有则一直重复这个步骤,直到找到目标点或者遍历完整个地图。

学过二叉树的同学激动地拍了拍大腿,这不就是前序遍历嘛,那这个遍历的方式我们可以简单的写成:

/* * describe  : 前序便利* parameter : bt_node 指向根节点的指针*             id 查找到的节点ID*             pre_node 指向当前找到的节点* return    : 指向id符合的节点的指针*/
static void ErgodicTree(BTNode* bt_node)
{if(bt_node == NULL){//        DEBUG("ErgodicTree bt_node == NULL \r\n");return;}/***** 这里查看当前节点信息,比如判断当前节点是否为终点等 *****//*********************************************************/ErgodicTree(bt_node->firstchild); ErgodicTree(bt_node->rightsib);
}// describe  : 前序遍历,执行所有叶子结点的函数指针指向
// parameter : tree 树的地址
// return    : None
void DisBehaviorTree(const BTTree* tree)
{if(tree == NULL){DEBUG("DisBehaviorTree error \r\n");return;}ErgodicTree(tree->root);
}

这里用的是递归的方式,当地图比较大时,频繁递归频繁出入栈会增加算法开销,比较常见的方式是用栈模拟递归算法,比如找到子节点时将子节点push到栈里,直到找不到子节点时,一路pop直到有新的子节点。非递归实现网上很多资料,这里不多赘述。

广度优先

广度优先和深度优先思路不太一样,深度优先是一路找到终端节点(无任何子节点的节点),然后一路返回找新的终端节点,且满足左中右的遍历顺序。重复这个步骤即可。

广度优先是找到当前节点下的所有子节点,并且依次遍历完毕,然后找到根节点第一个子节点,遍历这个子节点下的所有子节点,然后回到根节点的第二个子节点,遍历这个子节点下的所有子节点。重复这个步骤,直到遍历到根节点的最后一个子节点,直到

  1. 广度优先是找到当前节点下的所有子节点,并且依次遍历完毕
  2. 然后找到根节点第一个子节点,遍历这个子节点下的所有子节点
  3. 然后回到根节点的第二个子节点,遍历这个子节点下的所有子节点
  4. 重复这个步骤,直到遍历到根节点的最后一个子节点
  5. 然后回到根节点的第一个子节点,将这个子节点作为根节点,重复 1 2 3 4 步骤,直到图中所有节点遍历完毕,或者找到目标点。

迪杰斯特拉算法

算法思想

迪杰斯特拉算法是在广度优先搜索算法的基础上,加上了贪心算法的思想,即遍历完当前节点的所有子节点后,不从第一个子节点开始进行遍历,而是从这些子节点中,路径代价最少的节点开始进行遍历,且每一次切换根节点时,都进行路径代价最少这个约束条件的判断。

PS:路径代价一般是根据根节点到该节点的最短距离,反映拓扑地图中就是边的长度,根节点的路径代价肯定是0,其他节点的路径代价,则是从根节点到该节点的最短距离,以不同的路径到这个节点的距离是不同的,所以最短距离是时刻在更新的。

matlab实现

% 基于栅格地图的机器人规划路径算法
% 第二节:迪杰斯特拉算法
clc
clear
close%% 栅格界面、场景定义
% 行数和列数
rows = 10;
cols = 20;
[field,cmap] = defColorMap(rows,cols);% 起点、终点、障碍物区域
startPos = 2;
goalPos = 198;
field(startPos) = 4;
field(goalPos) = 5;%% 算法初始化
% S/U的第一列表示栅格地图节点线性索引编号
% 对于S,第二列表示从源节点到本节点以求得的最小距离,不在变更
% 对于U,第二列表示从源节点到本节点暂时求得的最小距离,可能会变更
U(:,1) = (1:rows*cols);
U(:,2) = inf;
S = [startPos,0];   % 把起点装进U集合中
U(startPos,:) = []; % 删除U集合中的起始节点信息% 更新起点的邻接点及代价
neighborNodes = getNeighborNodes(rows,cols,startPos,field);
for i = 1:8childNode = neighborNodes(i,1);% 判断孩子节点是否存在if ~isinf(childNode)idx = find(U(:,1) == childNode); % 找到在U集合中相等的线性索引U(idx,2) = neighborNodes(i,2);end
end% S集合的最优路径集合
for i = 1 : rows*colspath{i,1} = i;
end
for i = 1:8childNode = neighborNodes(i,1);if ~isinf(neighborNodes(i,2)) % 代价不为空path{childNode,2} = [startPos,neighborNodes(i,1)]; % 存放从起点到其他子节点的坐标,[起点坐标,子节点坐标](均为线性索引)end
endisEndLoop = false;while ~isempty(U) && ~isEndLooppause(0.1);% 在U集合中找出当前最小距离值的节点,视为父节点,并移除该节点至S集合中[dist_min,idx] = min(U(:,2));parentNode = U(idx,1);S(end+1,:) = [parentNode,dist_min];U(idx,:) = [];if parentNode == goalPosisEndLoop = true;end% 获取当前节点的临近节点neighborNodes = getNeighborNodes(rows,cols,parentNode,field);% 依次遍历邻近子节点,判断是否在U集合中更新邻近节点的距离值for i = 1:8% 需要判断的子节点childNode = neighborNodes(i,1);cost = neighborNodes(i,2);if ~isinf(childNode) && ~ismember(childNode, S)% 找出U集合中节点childNode的索引值idx_U = find(childNode == U(:,1));if field(U(idx_U,1)) ~=  2 && field(U(idx_U,1)) ~=  4 && field(U(idx_U,1)) ~=  5field(U(idx_U,1)) = 7;end% 画栅格图image(1.5,1.5,field);grid on;set(gca , 'gridline' , '-' , 'gridcolor' , 'k' , 'linewidth' , 2 , 'GridAlpha' , 0.5);set(gca , 'xtick' , 1 : cols + 1,'ytick',1 : rows + 1);axis image;% 判断是否需要更新if dist_min + cost < U(idx_U,2);U(idx_U,2) = dist_min + cost;% 更新最优路径path{childNode,2} = [path{parentNode,2},childNode];endendend
end%% 画栅格界面
% 找出目标最优路径
path_opt = path{goalPos,2};
field(path_opt(2:end-1)) = 6;% 画出探索过的区域
for i = 1 : length(S)if ~isinf(S(i,2)) && S(i,1) ~= startPos && S(i,1) ~= goalPos && field(S(i,1)) ~= 6field(S(i,1)) = 7;end
end% 画栅格图
image(1.5,1.5,field);
grid on;
set(gca , 'gridline' , '-' , 'gridcolor' , 'k' , 'linewidth' , 2 , 'GridAlpha' , 0.5);
set(gca , 'xtick' , 1 : cols + 1,'ytick',1 : rows + 1);
axis image;

画出该算法的动态演示图:



可以看到在不同场景的栅格地图下,迪杰斯特拉算法都能准确地找到终点,并且算出最短路径。

总结

对于在栅格场景下的迪杰斯特拉算法来讲,贪心策略基本宣告无效,因为每个节点之间的距离都是固定的1/1.4(直边或者斜边),这时的迪杰斯特拉算法 = 广度优先搜索算法 = 低效率但高覆盖率

机器人路径规划之迪杰斯特拉算法(二)相关推荐

  1. PTA旅游规划(迪杰斯特拉算法)

    思路:迪杰斯特拉算法求最短路径,只是需要考虑花费钱的最小值进行刷新(当路径相同时) PS:迪杰斯特拉算法求有起点和终点的最短路径区分最小生成树. #include<iostream> #i ...

  2. java迪杰斯特拉算法实例,Java 图的最短路径dijstra(迪杰斯特拉)算法和拓扑排序

    一.图的最短路径从某顶点出发,沿图的边到达另一顶点所经过的路径中,各边上权值之和最小的一条路径叫做最短路径 图的最短路径有许多重要的应用. 例如:上图中v0-v8有9个点,可以看做不同的地点,现在要规 ...

  3. 校园导游系统_C语言实现_Dijkstra(迪杰斯特拉算法)_数据结构

    西京学院导游系统 摘要   要完成对整个导游图系统的功能实现,需要对每一项功能都有清楚的设想和认识,了解并明确每一项功能的实现和需要解决的问题,选择正确并且高效的算法把问题逐个解决,最终实现程序的正确 ...

  4. 迪杰斯特拉算法及变式(最短距离,打印路径,最短经过节点数)

    问题描述 给定一个图,图的节点名称用(000 ~ N−1N - 1N−1)表示.NNN为图的节点个数,MMM为边的个数,SSS为起始点. 输入条件: 第一行输入 NMSN M SNMS. 其后MMM行 ...

  5. MATLAB轻松绘制地图路线——Dijkstra(迪杰斯特拉)算法最短路径规划

    文章目录 1. 地图绘制 2. 计算各节点之间的距离 3. Dijkstra(迪杰斯特拉)算法 4. 根据计算出的距离利用Dijkstra(迪杰斯特拉)算法找出指定节点之间的最短路径 工程文件(可直接 ...

  6. c++ 遍历所有点且距离最短_图解:最短路径之迪杰斯特拉算法

    小禹禹们,你们好,景禹最近已经开学,忙着准备毕业答辩的事情,这才抽身个大家更新文章,还请莫怪.生活实属不易,有时候让人有点儿焦头烂额,甚至想让景禹放弃继续更新文章,可是千百号人默默地关注者景禹,当然也 ...

  7. >算法笔记-动态规划-最短路径迪杰斯特拉算法

    算法笔记-动态规划-最短路径迪杰斯特拉算法 作者:星河滚烫兮 前言   图的最短路径问题在现实生活中有很广阔的应用,最短路径又分为单源最短路径与多源最短路径,前者求出固定起点到其他节点的最短路径,后者 ...

  8. 迪杰斯特拉算法(Dijkstra‘s algorithm)以及示例

    迪杰斯特拉算法(Dijkstra's algorithm)是一种非常重要且有价值的算法.它被广泛应用于计算图中单源最短路径问题,在交通路线规划.网络路由.作业调度等领域有着广泛的应用. 迪杰斯特拉算法 ...

  9. 迪杰斯特拉算法(C语言实现)

    迪杰斯特拉算法(C语言实现) 如上图,求以a为源点到个顶点的最短路劲. #include "stdio.h" #include "stdlib.h" //用一个 ...

最新文章

  1. linux shell 判断字符串是否在数组中
  2. Synergy软件的基本配置/使用(详细教程)
  3. LeetCode Self Crossing(判断是否相交)
  4. 廖雄南昌大学计算机系,南昌市社区老年性痴呆患病率及其影响因素
  5. 超级详细备注的代码:Python帮助您高效通过英语六级考试
  6. matlab anova 如何不画图,方差分析的数据处理和作图
  7. 【干货】2021顾客体验十二大趋势:从“千人一面”到“千人千面”.pdf(附下载链接)...
  8. 吴恩达新书手稿完工,现在开放免费下载 | 资源
  9. 一种基于JSON语法的JSON数据转换器
  10. 孙玄:构建企业级业务高可用的延时消息中台
  11. 海康威视二次开发 python_海康威视面试python后端题
  12. 插图详解Python解决汉诺塔问题
  13. pandas删除最后一列_Python中pandas dataframe删除一行或一列:drop函数详解
  14. office2013 打开报错 无法访问您试图使用的功能所在的网络位置
  15. (P57-P61)正则表达式
  16. DSB matlab仿真
  17. Revit二次开发小技巧(十二)创建带洞口的墙
  18. 别人的18岁,恐怕会碾压你的38岁
  19. 面经(一)人生第一次面试—一首凉凉送给自己
  20. 【C/C++】内存对齐(超详细,看这一篇就够了)

热门文章

  1. python 循环播放音乐_基于python实现音乐播放器代码实例
  2. 自己写的一个类淘宝手机端图片浏览双指缩放的功能
  3. ImageJ 图片转GIF 视频转图片
  4. java计算机毕业设计高校图书馆管理网站源码+mysql数据库+系统+lw文档+部署
  5. apereo cas开发_统一认证 - Apereo CAS 小试
  6. 三极管和MOS管工作原理详解
  7. 访问服务器80端口显示iis,iis服务器80端口一直与本机建立连接解决思路
  8. 简约淡雅中国国学传统文化PPT模板
  9. 开启推广商业活动之前,先确定目标。——Google Adwords
  10. 神州数码DCWS-6028命令总结(二)