当前位置:   article > 正文

A*算法简介-matlab篇_matlab a星算法

matlab a星算法

如果你对A*多少有过了解,但是不知道如何编程,这篇文章可以帮助你;

如果你对A*毫无了解,想熟悉了解下,这篇文章和参考文章可以帮助你;

如果你对A*了如指掌,并且是算法大师,这篇文章帮不到你,请指教一下。

我接下来基本上所有文章都是针对Atsushi Sakai这个作者在GitHub上发布的,添加注释以及自己的一些思考,希望可以帮助到一些新入门的人。希望大家对机器人方面的算法都大致有个了解,然后选择合适的算法,改进下,用到自己的学习中或者工作中去。

A星算法核心公式就是F值的计算:[1]
F = G + H

F - 方块的总移动代价
G - 开始点到当前方块的移动代价
H - 当前方块到结束点的预估移动代价

A*算法的逻辑:[2]

 

  1. function [] = AStarSample()
  2. %AStarSample() A*法による最短?路探索プログラム
  3. %
  4. % Author: Atsushi Sakai
  5. %
  6. % Reference:A*による最短?路探索MATLABプログラム - MY ENIGMA
  7. % http://d.hatena.ne.jp/meison_amsl/20140503/1399080847
  8. %
  9. % Copyright (c) 2014, Atsushi Sakai
  10. % All rights reserved.
  11. % License : Modified BSD Software License Agreement
  12. clear all;
  13. close all;
  14. disp('A Star Path Planning start!!');
  15. %参数
  16. p.start=[1,1]; %起始点
  17. p.goal=[10,3]; %目标点
  18. p.XYMAX=11; %地图的最大高度和宽度
  19. %获取边界数据
  20. obstacle=GetBoundary(p);
  21. %获取障碍物数据与边界数据一起获取
  22. nObstacle=20;%障碍物数量
  23. obstacle=GetObstacle(nObstacle,obstacle,p);
  24. %最短路径生成
  25. path=AStar(obstacle,p);
  26. %创建图
  27. figure(1)
  28. if length(obstacle)>=1
  29. plot(obstacle(:,1),obstacle(:,2),'om');hold on;
  30. end
  31. plot(p.start(1),p.start(2),'*r');hold on;
  32. plot(p.goal(1),p.goal(2),'*b');hold on;
  33. if length(path)>=1
  34. plot(path(:,1),path(:,2),'-r');hold on;
  35. end
  36. axis([0-0.5 p.XYMAX+1+0.5 0-0.5 p.XYMAX+1+0.5])
  37. grid on;
  38. end
  39. function path=AStar(obstacle,p)
  40. % 一个通过A *方法找到最短路径的程序
  41. % 返回最短路径的坐标列表
  42. path=[];%路径
  43. %用于在计算过程中存储节点信息[x,y,cost,px(父节点),py(父节点)]存储起始节点
  44. open=[p.start(1) p.start(2) h(p.start,p.goal) p.start(1) p.start(2)];
  45. close=[];%用于存储计算的节点信息
  46. %到相邻节点的运动模型通过更改此参数,可以指定机器人的运动
  47. next=MotionModel();
  48. findFlag=false;%目标发现标志
  49. while ~findFlag
  50. %如果没有open列表中没有点了,而且还没有找到目标点,则找不到路径。
  51. if isempty(open(:,1)) disp('No path to goal!!'); return; end
  52. %选择成本最低的开放节点,类似于优先队列,把cost最低的点放到最前面
  53. [Y,I] = sort(open(:,3));
  54. open=open(I,:);
  55. %目标判断
  56. if isSamePosi(open(1,1:2),p.goal) %判断这个点是不是目标点
  57. disp('Find Goal!!');
  58. %将目标节点移至“关闭”的开头
  59. close=[open(1,:);close];open(1,:)=[];
  60. findFlag=true;
  61. break;
  62. end
  63. for in=1:length(next(:,1))
  64. %计算相邻节点的位置和成本
  65. m=[open(1,1)+next(in,1) open(1,2)+next(in,2) open(1,3)];%open(1,1:2)作为父节点,计算周边点的位置,权重此时是父节点的权重
  66. %公式F= G + H;
  67. %m(3)+next(in,3)相当于G,h(m(1:2),p.goal)相当于H,这里我认为减这一项h(open(1,1:2),p.goal)没有必要,可有可无。
  68. m(3)=m(3)+next(in,3)+h(m(1:2),p.goal)-h(open(1,1:2),p.goal);%计算成本-h(open(1,1:2),p.goal)
  69. %如果相邻节点是障碍物,则查找下一个节点
  70. if isObstacle(m,obstacle) continue; end
  71. %在打开和关闭列表中搜索m
  72. [flag, targetInd]=FindList(m,open,close);
  73. if flag==1 %如果在open列表上,注意是同一个节点的两个不同路径的估价值
  74. if m(3)<open(targetInd,3) %如果新得到的cost小于open列表中的cost值
  75. open(targetInd,3)=m(3);%更新权重,和父节点
  76. open(targetInd,4)=open(1,1);
  77. open(targetInd,5)=open(1,2);
  78. end
  79. elseif flag==2 %如果在close列表中,注意是同一个节点的两个不同路径的估价值
  80. if m(3) < close(targetInd,3)%小于之前计算的
  81. vpa(m(3),10)
  82. vpa(close(targetInd,3),10)
  83. %更新父节点
  84. close(targetInd,4)=open(1,1);
  85. close(targetInd,5)=open(1,2);
  86. open=[open; close(targetInd,:)];
  87. close(targetInd,:)=[];%转到打开列表
  88. end
  89. else %如果两者都不
  90. %添加到带有父节点索引的打开列表
  91. open=[open;[m open(1,1) open(1,2)]];
  92. end
  93. end
  94. %相邻节点计算出的打开节点移动到关闭节点
  95. if findFlag==false
  96. close=[close; open(1,:)];
  97. open(1,:)=[];
  98. end
  99. %路径搜索的步骤动画
  100. % animation(open,close,p,obstacle);
  101. end
  102. %获取最短路径坐标列表
  103. path=GetPath(close,p.start);
  104. end
  105. function result=h(a,b)
  106. %启发式功能
  107. %这里,二维空间中a和b之间的范数距离
  108. result=norm(a-b);
  109. end
  110. function obstacle=GetObstacle(nob,obstacle,p)
  111. %创建一些由随机数指定的障碍,
  112. %一个函数,返回除起始点或目标点之外的任何东西
  113. %用随机数创建障碍
  114. ob=round(rand([nob,2])*p.XYMAX);
  115. %忽略是否在开始和目标处设置障碍
  116. removeInd=[];%用于存储要删除的障碍物索引的列表
  117. for io=1:length(ob(:,1))
  118. if(isSamePosi(ob(io,:),p.start) || isSamePosi(ob(io,:),p.goal))
  119. removeInd=[removeInd;io];
  120. end
  121. end
  122. ob(removeInd,:)=[];%清单
  123. obstacle=[obstacle;ob];
  124. end
  125. function result=isSamePosi(a,b)
  126. %确定2x1向量是否相同的函数
  127. result=false;
  128. if a(1)==b(1) && a(2)==b(2)
  129. result=true;
  130. end
  131. end
  132. function boundary=GetBoundary(p)
  133. % 采集区域边界数据
  134. boundary=[];
  135. for i1=0:(p.XYMAX+1)
  136. boundary=[boundary;[0 i1]];
  137. end
  138. for i2=0:(p.XYMAX+1)
  139. boundary=[boundary;[i2 0]];
  140. end
  141. for i3=0:(p.XYMAX+1)
  142. boundary=[boundary;[p.XYMAX+1 i3]];
  143. end
  144. for i4=0:(p.XYMAX+1)
  145. boundary=[boundary;[i4 p.XYMAX+1]];
  146. end
  147. boundary=[boundary;[11 11]];
  148. boundary=[boundary;[9 1]];
  149. boundary=[boundary;[10 2]];
  150. boundary=[boundary;[11 3]];
  151. boundary=[boundary;[10 1]];
  152. boundary=[boundary;[11 2]];
  153. boundary=[boundary;[11 1]];
  154. end
  155. function animation(open,close,p,obstacle)
  156. % 顺序显示搜索状态的功能
  157. figure(1)
  158. if length(obstacle)>=1
  159. plot(obstacle(:,1),obstacle(:,2),'om');hold on;
  160. end
  161. plot(p.start(1),p.start(2),'*r');hold on;
  162. plot(p.goal(1),p.goal(2),'*b');hold on;
  163. plot(open(:,1),open(:,2),'xr');hold on;
  164. plot(close(:,1),close(:,2),'xk');hold on;
  165. axis([0-0.5 p.XYMAX+1+0.5 0-0.5 p.XYMAX+1+0.5])
  166. grid on;
  167. pause;
  168. end
  169. function flag=isObstacle(m,obstacle)
  170. for io=1:length(obstacle(:,1))
  171. if isSamePosi(obstacle(io,:),m(1:2))
  172. flag=true;return;
  173. end
  174. end
  175. flag=false;%不是障碍
  176. end
  177. function next=MotionModel()
  178. %到相邻节点的运动模型通过更改此参数,可以指定机器人的运动
  179. % [x y cost]
  180. next=[1 1 1
  181. 1 0 1
  182. 0 1 1
  183. -1 0 1
  184. 0 -1 1
  185. -1 -1 1
  186. -1 1 1
  187. 1 -1 1];
  188. end
  189. function path=GetPath(close,start)
  190. %获取从开始到目标的坐标列表的功能
  191. ind=1;%目标在关闭列表的顶部
  192. path=[];
  193. while 1
  194. %在列表中注册坐标
  195. path=[path; close(ind,1:2)];
  196. %确定您是否已到达起点
  197. if isSamePosi(close(ind,1:2),start)
  198. break;
  199. end
  200. %在关闭列表中查找父节点
  201. for io=1:length(close(:,1))
  202. if isSamePosi(close(io,1:2),close(ind,4:5))
  203. ind=io;
  204. break;
  205. end
  206. end
  207. end
  208. end
  209. function [flag, targetInd]=FindList(m,open,close)
  210. targetInd=0;
  211. %是否在open数组中
  212. if ~isempty(open)
  213. for io=1:length(open(:,1))
  214. if isSamePosi(open(io,:),m(1:2))
  215. flag=1;
  216. targetInd=io;
  217. return;
  218. end
  219. end
  220. end
  221. %是否在close数组中
  222. if ~isempty(close)
  223. for ic=1:length(close(:,1))
  224. if isSamePosi(close(ic,:),m(1:2))
  225. flag=2;
  226. targetInd=ic;
  227. return;
  228. end
  229. end
  230. end
  231. %都没有
  232. flag=3;return;
  233. end

这是matlab版本的,他后续的还有个python版本,等我注释都写好后,再发上来。我还准备了一个公众号,到时候把二维码贴上来。方便大家接收更新。

大家有不明白的可以留言,重点区域再更新下。

参考文献

[1] https://www.cnblogs.com/leoin2012/p/3899822.html

[2] Youtube视频

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/218637
推荐阅读
相关标签
  

闽ICP备14008679号