欢迎访问 生活随笔!

生活随笔

当前位置: 首页 >

什么是A*(Astar)算法?(简单叙述)

发布时间:2023/12/14 50 豆豆
生活随笔 收集整理的这篇文章主要介绍了 什么是A*(Astar)算法?(简单叙述) 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

目录

简介

A*算法的原理与思想

A*算法处理与搜索

实例(引用见文末)


 

简介

A*算法(启发式搜索)的首要条件是在静态路网中,相对于广度优先遍历(BFS)求最短路径的最有效算法(BFS缺点是效率低耗时久,而A*更高效)。

A*BFS
高效率耗时短低效率耗时久

A*算法,A*(A-Star)算法是一种静态路网中求解最短路径最有效的直接搜索方法,也是解决许多搜索问题的有效算法。算法中的距离估算值与实际值越接近,最终搜索速度越快。

宽度优先搜索算法(又称广度优先搜索,简称BFS)是最简便的图的搜索算法之一,这一算法也是很多重要的图的算法的原型。

A*算法的原理与思想

运用了一个很重要的式子:f(n)=g(n)+h(n)

起点至终点的x轴与y轴距离之和即为曼哈顿距离。

如图黄色线与红色线的长度即为曼哈顿距离的值。

A*算法结合了贪心算法(深度优先)与Dijkatra算法(广度优先),优先计算代价更低的方向。

A*算法处理与搜索

  • 将整个地图网格化,可以理解为化为一个个像素点,即栅格法,将每一个像素点作为一个节点。
  • 给每一个节点定义一个属性:①可通过②不可通过。如图中黑色格可通行,蓝色格不可通行。
  • 定义一个列表集合openlist和closelist,给每一个节点都可有一个状态openlist或closelist,分别属于两个集合。(属性为不可通过的节点默认为closelist状态,该节点就属于closelist集合)
  • openlist为待考察节点,closelist为已考察节点。先以初位置节点A为父节点,其状态为closelist,以其为中心的九宫格的其余八个节点为子节点,都附加状态openlist。
  • 定义横纵移动的代价为10,斜向移动大家为14.每个方格左上角为f(n),左下角为g(n),右下角为h(n)
  • 选择f(n)值最小的节点B。
  • 检查B周围的方格,首先考察g(n),其他 4 个相邻的方格均在 open list 中,我们需要检查经由这个方格到达那里的路径是否更好,使用g(n) 值来判定。
  • 让我们看看B上面的方格。它现在的 g(n) 值为 14 。如果我们经由当前方格到达那里, g(n)值将会为 20(其中 10 为到达当前方格的 g(n) 值,此外还要加上从当前方格纵向移动到上面方格的 g(n) 值 10) 。显然 20 比 14 大,因此这不是最优的路径。如果你看图你就会明白。直接从起点沿对角线移动到那个方格比先横向移动再纵向移动要好。
  • 而如果有更小的g(n)值再考察h(n),按照曼哈顿距离计算估计代价,再计算出f(n)=g(n)+h(n)的值。
  • 以B子节点为新的父节点,其余子节点放入closelist,选择周围f(n)最小的节点,发现上下两格都是54,我们选择下方的格子C。
  • 以此类推,分别计算出剩余openlist的节点的f(n)值,挑选最小的代价节点一刀closelist中。
  • 从openlist中选择f(n)最小的节点放入closelist中并将它视作新的父节点,按照以上步骤类推,不断的重复,一直到搜索到终点节点,完成路径搜索,结束算法。
  •  要注意,例如以C为父节点后,C的右下方为墙的下方,而C不能通过对角线到墙的下方,故忽略墙的周围格子的对角线通行。
  • 实例(引用见文末)

    如图浅绿色点到草绿色点。

    clear; clc; clf; figure(1); map =[ 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 .3 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 .7 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ]; pcolor(map) colormap summer [row,col] = size(map); [start_px,start_py] = find(map == .3); [end_px,end_py] = find(map == .7);close = struct([]); closelen = 0; open = struct([]); openlen = 0;%% 将起点添加到open列表 open(1).row = start_px; open(1).col = start_py; open(1).g = 0; open(1).h = abs(end_py - start_py) + abs(end_px - start_px); openlen = openlen + 1; %% 四种运动格式 sport = [0,1;0,-1;-1,0;1,0]; backNum = 0; prev = []; while openlen > 0%% 获取代价最小的值for i = 1:openlenf(i,:) = [i,open(i).g + open(i).h]; endf1 = sortrows(f,2);current = open(f1(1));choose = 0;chooseArr = [];%% 回溯将走过的点标记出来if current.row == end_px && current.col == end_pyi = 1;while(i<=size(prev,1))if prev(i,3) == current.row && prev(i,4) == current.colchoose = choose +1;chooseArr(choose,1) = prev(i,1);chooseArr(choose,2) = prev(i,2);current.row = prev(i,1);current.col = prev(i,2);i = 1;elsei = i + 1;endend for j = 1: size(chooseArr,1)map(chooseArr(j,1),chooseArr(j,2)) = 0.5;endfigure(2);pcolor(map);colormap winter;return; endcloselen = closelen + 1;close(closelen).row = open(f1(1)).row;close(closelen).col = open(f1(1)).col;close(closelen).g = open(f1(1)).g;close(closelen).h = open(f1(1)).h; open(f1(1)) = [];openlen = openlen -1; for i = 1:4dimNormal = all([current.row,current.col]+sport(i,:)>0) ...&& current.row+sport(i,1)<=row && current.col+sport(i,2)<=col;neighbor.row = current.row + sport(i,1);neighbor.col = current.col + sport(i,2);neighbor.g = abs(start_px - neighbor.row) + abs(start_py - neighbor.col);neighbor.h = abs(end_px - neighbor.row) + abs(end_py - neighbor.col);if dimNormalinCloseFlag = 0; if closelen ==0elsefor j = 1:closelenif close(j).row == neighbor.row && close(j).col ==neighbor.colinCloseFlag = 1;break;endendendif inCloseFlagcontinue;endtemp_g = current.g + abs(current.row - neighbor.row) + abs(current.col - neighbor.col);inOpenFlag = 0;for j =1:openlenif open(j).row == neighbor.row && open(j).col ==neighbor.colinOpenFlag = 1;break;endend if ~inOpenFlag && map(neighbor.row,neighbor.col) ~= 1openlen = openlen + 1;open(openlen).row = neighbor.row;open(openlen).col = neighbor.col;open(openlen).g = abs(start_px - neighbor.row) + abs(start_py - neighbor.col);open(openlen).h = abs(end_px - neighbor.row) + abs(end_py - neighbor.col); elseif temp_g >= neighbor.gcontinue;endbackNum = backNum +1;prev(backNum,:) = [current.row ,current.col,neighbor.row ,neighbor.col];neighbor.g = temp_g; elsecontinue;endend end

       结果为

    参考与引用http://www.gamedev.net/reference/articles/article2003.asp

                     https://b23.tv/I3GLzp

                     https://blog.csdn.net/lmq_zzz/article/details/88999480

    总结

    以上是生活随笔为你收集整理的什么是A*(Astar)算法?(简单叙述)的全部内容,希望文章能够帮你解决所遇到的问题。

    如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。