【转载】启发式搜索技术A*【译】

原文网址:http://www.cnblogs.com/yanlingyin/archive/2012/01/15/2322640.html

以下为原文:

这篇文章介绍找最短路径的一种算法,它的字我比较喜欢:启发式搜索。

标题上写的是翻译,只是觉得原文讲解的思路很清晰。这篇文章整体构思和原文相差不多,只是有些地方有小的改动,

我想的是用更容易理解的方式、更简洁的把A*算法的思想呈现出来。

文章中出现的词openlist,closelist我觉得用原文会更好故没有翻译,在文中会有解释。

原文地址http://www.gamedev.net/page/resources/_/technical/artificial-intelligence/a-pathfinding-for-beginners-r2003

各位也可以直接参考原文。

网上关于A*算法的文章还有很多,只是那些都需要有一定的基础,对于入门的好文章不多,而这篇文章就是为初学者而写的,很适合入门的一篇。文章定位:非专业性A*文章,很适合入门。

有图有真相,先给大家看个效果图吧:从图的左下角到右上角寻找最短路径,灰色部分是障碍物。

这是用一般的搜素方法,类似穷举的效果

下面的图是用A*搜素的效果,也就是本文要介绍的算法。

可以看出,用A*算法减少了许多计算量,它的效率有了显著的提高。

下面将为你解答上图中的算法是如何实现的。

图片来源:http://en.wikipedia.org/wiki/A*_search_algorithm

正文

搜索区域介绍

下图是这篇文章讨论的中心:

图中左边的绿色点是搜索的起点A,目标点是右边的红色点B,中间被障碍物挡住(蓝色部分)。

我们的目的是从起点出发,找到一条到达目标点的最短路径。

把整个图都分为一个个小方块只是为了这样方便讨论,更多的应用中,也可以把图分为其它方块的组合。

开始搜索

目标是找出从A点出发到B的最短路径,所以我们从A点开始搜索,直到找到目标B。

搜索的步骤是这样的:

1、从起点A开始把A加入到openlist中。openlist解释:它是一个队列,里面元素是一些方块,它们有可能构成最短路径。现在队列中只有元 素A,以后会加入更多的元素。以后会对里的元素进行检查,从里面来找到构成最短路径的元素。

2、看起点A周围的元素是否可达(是否能从A到达它们)把从A可到达的元素加入到openlist中,并且加入到openlist中的节点维护一个指指针,指向他的父亲,也即A点。如果A周围有障碍物就忽略它。从这个图看, A周围把个元素都可达,所以把它们都加到openlist中。

3、把起点A放入closelist中,在closelist中的点意味着以后不需要再去考虑它了。对于A节点,A可达的点都加入到了openlist中,以后也就不用考虑A的情况了。

经过以上三步操作后的效果图如下所示

图中被暗绿色包围的就是openlist中的点,一共八个,都是从起点A可达的点,并且他们中的每个都有一个指向他们父节点的指针(图中的小针方向)被高亮绿色包围的表示closelist中的点,可以看出起点A已经在closelist中。

路径选择

从起点出发 ,下一步可以走的点现在有八个,选取哪一个作为下一步的点呢?正常的思维是选取一个离目标值最进,且在这些点中离远点最近的点。

本文的思路也是这样的,文中用

F = G + H

表示,其中:

对于每个点,都有自己的G、H、F。

其中G表示从特定的点到起点的距离,H表示从该点到目标的估值,那么F就是经过该点路径的估值。

下面详细介绍

G:从起点到特定节点的距离,也就是G的父节点加上从G的父节点到起点A的距离g。图中是边长为10的正方形块,所以就是G的父节点的值g

加上10(上下左右相邻)或者加上14(斜块相邻、也就是对角线的长度,本来是14.14、、为了方便计算这里取近似值)

H:H能用很多方法得到估计值.这里用到的方法称为Manhattan method,H的值就是从考虑的点通过水平和垂直移动达到目标点的移动步数乘10(正方形块的边长为10).注意只是水平和垂直移动,不走斜线。并且忽略图中的障碍物。

插一句:

看了对H的描述,你可能会怀疑这种估计的精确性,有一点是可以肯定的:估计值越接近真实值,算法就能更块的找出最短路径。我们用的这种方法确实是做了估计,只是这种估计准确性不高,就是说只是粗略的估计,因为这种方法容易理解,所以才采用这种方法。可以想到,太过接近的估值最后不一定能得到想要的结果。关于估值函数想了解更多请参见:http://www.policyalmanac.org/games/heuristics.htm

为了从openlist中选取一个点继续搜索,就要计算出openlist中的每个点的F、H、G的值然后选取F小的一个点,进行下一步的探索。

对于上图中的点,他们的F、G、H的值在图中都有标明。

F、H、G的位置在起点右边的点中已经有标注,其他点的位置同理。

现在看起点右边的点(也就是标有字母的点)G=10,因为在起点正左边。H=30,水平移动三个格子可以到目标点B。F=G+H=40

继续搜索

由于我们的目的是找最短路径 ,下一步就从openlist中选取F最小的点做进一步的搜索,按如下步骤进行:

(为了方便描述,把选取的点成为点M)

1、检查M周围的点,在closelist中则忽略它,如果可达且不在openlist中,则加入openlist中,同理的维护一个指向父节点的指正,同时计算加入点的F H G 值。

2、如果M周围的点在openlist中,则看从起点A通过M到这类点的路径是不是小于他们的G值,如果是则更新他们的G、F值(更新为小的)。如果不是则不做任何操作。

3、把M从openlist中移除,加入closelist中。

对openlist中F最小的点(也就是起点左边的点)的处理效果如下图所示:

M的右边、右上、右下是障碍物,所以忽略他们。M的左边点在closelist中,也不去管他,剩下的是M的上、下、左上、左下的点。他们已经在openlist中,所以看从起点通过M到他们的距离是不是小于他们的G值。通过判断,都比他们的G值大,所以做任何操作。

可以看出,现在的closelist已有两个元素了(高亮绿色包围的块)

下一步的操作和上面叙述的一样,从openlist中找出F最小的,重复上的操作。从图中可以看出,现在的openlist中F最小的有两个,就是刚刚考虑的点的正上方和正下方,其实这里选哪个都无所谓,只是人们习惯于选择较晚加入到openlist中的元素,这里选择下方的点。

同理,处理效果如下图所示:

下面简单的说下处理过程:

暂且称现在处理的点为N吧。

N上方  在closelist中,不考虑。

N左方 在openlist中,看从原点通过N到它的距离为14+10大于10,不做操作,跳到下一步

N的左下方,下方 加入openlist中,同时记录F、G 、H的值还有指向父节点的指针。

N的右下方这里看做“不可达的点”原因是这两个点都处于障碍物的对角上,当然这只是一种人为的规定。也可以取消这条规定就把它加入到openlist中。这只是一种规定,不必深究。

处理的结果是closelist中现在有三个元素,用高亮的蓝色标记,同样的,openlist中的元素用暗绿色标记出。

重复上的步骤,每次从openlist中选取F最小的点加入closelist中,同时处理这个点周围的元素。。

直到目标节点也被加入到closelist中停止。

处理的效果如下图所示:

如果用心看、你也许已经发现了,在起点正下方两个点的G值,没错,就是图中用椭圆圈起来的点,之前的G=28,现在是20。这是在算法进行的时候更新的,可能 是这其中的某一步,处理这个点的时候,发现了一条更短的路径20,替换了原来的28。

到这里,问题已经基本解决了,最后的任务就是得到这条路径。

只要从目标点出发,沿着他们的父节点遍历,直到起点。就得到了一条最短路径。

如下图所示

总结

现在你应该对A*算法有一个初步的认识了吧,总结下算法的实现过程:

1、把起点加入到openlist中

2、重复以下步骤

  a、从openlist中找出F最小的节点,并把它当做当前的操作节点

  b、检查当前点周围的点,如果已经在openlist中看是否能通过当前点得到更小的G,如果能就更新那个点的G,F的值,如果在closelist中或者是障碍物(不可达)则忽略他们

  c、把当前点从openlist中移除 ,加入closelist中

  d、当目标点加入closelist中时停止

3、保存路径,从目标点出发,按照父节点指针遍历,直到找到起点。

后记

其实启发式搜索就是对穷举的一种优化,让每次搜索都更接近目标。这就要通过估值函数实现,对于这类问题,找到一个估值函数是关键。

估值函数:从当前点出发到目标点的花费。其实从这个理念上说,好像和分支界限法有些类似,都是在穷举的基础上对搜素优化。

如有转载请注明出处:

http://www.cnblogs.com/yanlingyin/

一条鱼~

尹雁铃@博客园

尹雁铃@博客园

时间: 2024-08-01 22:42:26

【转载】启发式搜索技术A*【译】的相关文章

【转载】技术的正宗与野路子

http://kb.cnblogs.com/page/554496/ http://zhangtielei.com/posts/blog-programmer-learn.html 黄衫女子的武功似乎与周芷若乃是一路,飘忽灵动,变幻无方,但举手抬足之间却是正而不邪,如说周芷若形似鬼魅,那黄衫女子便是态拟神仙. 这段描写出自<倚天屠龙记>第三十八回. "九阴神抓"本是<九阴真经>中的上乘武功,但当初梅超风夫妇由于拿到的<九阴真经>不完整,学不到里面的内

[转载] 搜索引擎技术介绍

转载自http://backend.blog.163.com/blog/static/202294126201252872124208/ 需求与历史 搜索引擎的诞生源自互联网最根本的用途之一:信息获取.在搜索引擎出现之前,互联网缺少入口,用户往往需要自己记住有用的网站和网页. 为了满足这种需求,最早的“搜索引擎”,即分类目录浏览式的引擎便出现了,Yahoo就是其中的代表. 当时只是把一些有用的网站通过分类的方式手工组织起来,便于用户找到有用的信息. 能够手工组织也是基于早年整个互联网的网站数量也

转载:技术的正宗与野路子

* 参考文章:http://mp.weixin.qq.com/s?__biz=MzA4NTg1MjM0Mg==&mid=2657261357&idx=1&sn=ebb11a1623e00ca8e6ad55c9ad6b2547#rd * 面对一项新技术的时候,我们怎样去学习才能循序渐进,最终理解得深刻? 让我们先把可供自学的资料列出来,分析一下: Tutorial(入门教程).由该项技术的官网提供.通常是英文的.这份资料是给初次接触该项技术的人看的,一般是一步一步地教你完成某些例子.

[转载] namespace技术

原文: http://www.infoq.com/cn/articles/docker-kernel-knowledge-namespace-resource-isolation namespace技术和cgroup技术是现阶段实现轻量级虚拟化的基石, 本文详细解释了namespace技术的基本原理, 对于理解namespace技术非常有帮助 Docker背后的内核知识——Namespace资源隔离 作者 孙健波 发布于 2015年3月12日 | 讨论 分享到:微博微信FacebookTwitt

启发式搜索技术A*

开篇 这篇文章介绍找最短路径的一种算法,它的字我比较喜欢:启发式搜索. 对于入门的好文章不多,而这篇文章就是为初学者而写的,很适合入门的一篇.文章定位:非专业性A*文章,很适合入门. 有图有真相,先给大家看个效果图吧:从图的左下角到右上角寻找最短路径,灰色部分是障碍物. 这是用一般的搜素方法,类似穷举的效果 下面的图是用A*搜素的效果,也就是本文要介绍的算法. 可以看出,用A*算法减少了许多计算量,它的效率有了显著的提高. 下面将为你解答上图中的算法是如何实现的. 图片来源:http://en.

转载-- Objective-C编码规范[译]

原文链接 : The official raywenderlich.com Objective-C style guide 原文作者 : raywenderlich.com Team 译文出自 : raywenderlich.com Objective-C编码规范 译者 : Sam Lau 由于我正在准备模仿饿了么这个app,到时可能有些iOS开发者参与进来.这时如果每个人的Objective-C编码风格都不一样,这样不易于保持代码一致性和难以Code Review.所以我在网上搜索到 The

android 转译特殊符号标签(转载)

转载自:转译特殊符号标签 /** * DealingCharacter.java * Description: * @author li.b * @version 2.0 * Jun 27, 2008 */ public class DealingCharacter { /** * Description: 转译特殊符号标签 * @param value 需要处理的字符串 * @return */ public static String filter(String value) { if(va

[转]一个“技术文化人”的片段感悟

作者简介 孟岩,曾任CSDN和<程序员>杂志技术总编.(本文来自<程序员>杂志2010年11期) 2003年我加入CSDN,6年之后离开.在2003年之后,我的技术身份就很难界定了.曾经有个朋友称我为“技术文化人”——不以软件开发为生,但整天都在拿软件开发来说事,与这个行业的整体关系可能比任何一个具体的程序员或者架构师都更密切.听上去像是一种恭维,又好像是暗讽,似乎我是站在戏台下面带头起哄的票友.其实在我看来,我与一线技术人的根本区别,在于关注的问题不同:他们关心的如何做好软件,我

转载:ie6,ie7兼容性总结

其实浏览器的不兼容,我们往往是各个浏览器对于一些标准的定义不一致导致的,因此,我们可以进行一些初始化,很多问题都很轻松解决. 下面是14条特殊情况仅供参考:1. 文字本身的大小不兼容.同样是font-size:14px的宋体文字,在不同浏览器下占的空间是不一样的,ie下实际占高16px,下留白3px,ff 下实际占高17px,上留白1px,下留白3px,opera下就更不一样了.解决方案:给文字设定 line-height .确保所有文字都有默认的 line-height 值.这点很重要,在高度