A星寻路入门双语版Astar Pathfinding for Beginners.docx
《A星寻路入门双语版Astar Pathfinding for Beginners.docx》由会员分享,可在线阅读,更多相关《A星寻路入门双语版Astar Pathfinding for Beginners.docx(26页珍藏版)》请在冰豆网上搜索。
![A星寻路入门双语版Astar Pathfinding for Beginners.docx](https://file1.bdocx.com/fileroot1/2023-2/3/43e56b26-4df2-433f-8075-9f8b428e776e/43e56b26-4df2-433f-8075-9f8b428e776e1.gif)
A星寻路入门双语版AstarPathfindingforBeginners
A*PathfindingforBeginners
ThisarticlehasbeentranslatedintoSpanishandFrench.Othertranslationsarewelcome.
Whileitiseasyonceyougetthehangofit,theA*(pronouncedA-star)algorithmcanbecomplicatedforbeginners.ThereareplentyofarticlesonthewebthatexplainA*,butmostarewrittenforpeoplewhounderstandthebasicsalready.Thisoneisforthetruebeginner.
虽然掌握了A*(读作A-star)算法就认为它很容易,对于初学者来说,它却是复杂的。
网上有很多解释A*的文章,不过大多数是写给理解了基础知识的人。
本文是给初学者的。
Thisarticledoesnottrytobethedefinitiveworkonthesubject.Insteaditdescribesthefundamentalsandpreparesyoutogooutandreadallofthoseothermaterialsandunderstandwhattheyaretalkingabout.Linkstosomeofthebestareprovidedattheendofthisarticle,underFurtherReading.
本文并不想成为关于这个主题的权威论文。
实际上它讨论了基础知识并为你做一些准备,以便进一步阅读其他资料和理解它们讨论的内容。
本文的后面列出了几个最好的文章,在进阶阅读中。
Finally,thisarticleisnotprogram-specific.Youshouldbeabletoadaptwhat'sheretoanycomputerlanguage.Asyoumightexpect,however,Ihaveincludedalinktoasampleprogramattheendofthisarticle.Thepackagecontainstwoversions:
oneinC++andoneinBlitzBasic.ItalsocontainsexecutablesifyoujustwanttoseeA*inaction.
最后,本文不是编程规范的。
你应该能够改写这里的东西到任何计算机语言上。
如你所期望的,同时,我包含了一个示例程序的链接,在本文后面结束的地方。
这个程序包有两个版本:
一个是C++,另一个用BlitzBasic语言编写。
如果你只是想看看A*的行为,里面也含有可执行exe文件。
Butwearegettingaheadofourselves.Let'sstartatthebeginning...
但我们要超越自己。
让我们从头开始...
介绍:
搜索区域Introduction:
TheSearchArea
Let'sassumewehavesomeonewhowantstogetfrompointAtopointBandthatawallseparatesthetwopoints.Thisisillustratedinthegraphicfoundbelow,withgreenbeingthestartingpointA,redbeingtheendingpointB,andthebluefilledsquaresbeingthewallinbetween.
我们假设某人想从A点到达B点,一堵墙把它们分开了。
如下图所示,绿色是开始点A,红色是结束点B,而蓝色填充的方块是中间的墙。
[图1][Figure1]
Thefirstthingyoushouldnoticeisthatwehavedividedoursearchareaintoasquaregrid.Simplifyingthesearcharea,aswehavedonehere,isthefirststepinpathfinding.Thisparticularmethodreducesoursearchareatoasimpletwodimensionalarray.Eachiteminthearrayrepresentsoneofthesquaresonthegrid,anditsstatusisrecordedaswalkableorunwalkable.ThepathisfoundbyfiguringoutwhichsquaresweshouldtaketogetfromAtoB.Oncethepathisfound,ourpersonmovesfromthecenterofonesquaretothecenterofthenextuntilthetargetisreached.
你应该注意的第一件事是,我们把搜索区域分割成了方块的格子。
简化搜索区域,如你目前完成的那样,这是寻路的第一步。
这个特殊方法把搜索区域简化成了一个二维数组。
数组的每一个项目代表了格子里的一个方块,它的状态记录成可行走和不可行走。
通过计算出从A到达B应该走哪些方块,就找到了路径。
一旦路径找到,我们的人从一个方块的中心移动到下一个方块的中心,直到抵达目标。
Thesecenterpointsarecalled"nodes".Whenyoureadaboutpathfindingelsewhere,youwilloftenseepeoplediscussingnodes.Whynotjustrefertothemassquares?
Becauseitispossibletodivideupyourpathfindingareaintosomethingotherthansquares.Theycouldberectangular,hexagons,oranyshape,really.Andthenodescouldbeplacedanywherewithintheshapes?
inthecenteroralongtheedges,oranywhereelse.Weareusingthissystem,however,becauseitisthesimplest.
这些中心点称作“节点”。
当你在其它地方阅读关于寻路时,你将经常发现人们讨论节点。
为什么不直接把它们认为是方块呢?
因为有可能你要把你的寻路区域以非方块的东西来分割。
它们可能是矩形,六角形,或任何形状,真的。
而节点可以放到形状内的任何位置。
在中心,或者沿着边缘,或其它地方。
然而我们使用这个系统,因为它最简单。
开始搜索StartingtheSearch
Oncewehavesimplifiedoursearchareaintoamanageablenumberofnodes,aswehavedonewiththegridlayoutabove,thenextstepistoconductasearchtofindtheshortestpath.InA*pathfinding,wedothisbystartingatpointA,checkingtheadjacentsquares,andgenerallysearchingoutwarduntilwefindourtarget.
一旦我们把搜索区域简化成了可以管理的大量节点,就象我们上面所做的那样采用格子的布局,下一步就是引导一个搜索来找出最短路径。
在A*寻路的做法,我们从开始点A做起,检查它周围的方块,并且向外普通的搜索,直到找到目标。
Webeginthesearchbydoingthefollowing:
我们这样开始搜索:
1.BeginatthestartingpointAandaddittoan"openlist"ofsquarestobeconsidered.Theopenlistiskindoflikeashoppinglist.Rightnowthereisjustoneitemonthelist,butwewillhavemorelater.Itcontainssquaresthatmightfallalongthepathyouwanttotake,butmaybenot.Basically,thisisalistofsquaresthatneedtobecheckedout.
2.从开始点A起,添加它到待考虑的方块的“开放列表”。
开放列表有点象购物列表。
此时只有一个项目在里面,但很快我们会得到更多。
它包含了你可能取用的沿途的方块,也可能不用它。
基本上,这是需要检查的方块的列表。
3.Lookatallthereachableorwalkablesquaresadjacenttothestartingpoint,ignoringsquareswithwalls,water,orotherillegalterrain.Addthemtotheopenlist,too.Foreachofthesesquares,savepointAasits"parentsquare".Thisparentsquarestuffisimportantwhenwewanttotraceourpath.Itwillbeexplainedmorelater.
4.观察开始点邻近的所有可到达或可行走的方块,忽略有墙,水或其他非法地形的方块。
也把它们添加到开放列表。
对每一个方块,保存A点作为它们的“父亲”。
这个父亲方块在跟踪路径时非常重要。
后面会更多的解释。
5.DropthestartingsquareAfromyouropenlist,andaddittoa"closedlist"ofsquaresthatyoudon'tneedtolookatagainfornow.
6.把开始方块A从开放列表中取出,并放到“封闭列表”内,它是所有现在不需要再关注的方块的列表。
Atthispoint,youshouldhavesomethinglikethefollowingillustration.Inthisdiagram,thedarkgreensquareinthecenterisyourstartingsquare.Itisoutlinedinlightbluetoindicatethatthesquarehasbeenaddedtotheclosedlist.Alloftheadjacentsquaresarenowontheopenlistofsquarestobechecked,andtheyareoutlinedinlightgreen.Eachhasagraypointerthatpointsbacktoitsparent,whichisthestartingsquare.
在此,你应该有了类似下图的东西。
在这个图中,中间的深绿色的方块就是开始方块。
它有浅蓝色的外框,表示它被添加到封闭列表了。
所有的相邻方块现在都进入要检查的方块的开放列表中了,它们有浅绿的外框。
每一个都有灰色的指针指回它的父亲,它就是开始方块。
[图2][Figure2]
Next,wechooseoneoftheadjacentsquaresontheopenlistandmoreorlessrepeattheearlierprocess,asdescribedbelow.Butwhichsquaredowechoose?
TheonewiththelowestFcost.
下一步,我们从开放列表中,选出一个相邻的方块,然后多多少少重复早先的过程,下面会说到。
但是我们选择哪一个呢?
具有最小F值的那个。
路径排序PathScoring
Thekeytodeterminingwhichsquarestousewhenfiguringoutthepathisthefollowingequation:
找到形成路径的方块的关键是下面的等式:
F=G+H
where
这里
∙G=themovementcosttomovefromthestartingpointAtoagivensquareonthegrid,followingthepathgeneratedtogetthere.
∙G=从开始点A到格子中给定方块的移动代价,沿着到达该方块而生成的那个路径。
∙H=theestimatedmovementcosttomovefromthatgivensquareonthegridtothefinaldestination,pointB.Thisisoftenreferredtoastheheuristic,whichcanbeabitconfusing.Thereasonwhyitiscalledthatisbecauseitisaguess.Wereallydon'tknowtheactualdistanceuntilwefindthepath,becauseallkindsofstuffcanbeintheway(walls,water,etc.).YouaregivenonewaytocalculateHinthistutorial,buttherearemanyothersthatyoucanfindinotherarticlesontheweb.
∙H=从格子中给定的方块到最终目标B点的评估移动代价。
这种方式通常称作试探法,有点让人混乱。
因为这是一个猜测,所以得到这个称谓。
在找到路径之前,我们真的不知道实际的距离,因为途中有各种东西(墙,水,等等)。
在本教程里给出了一种计算H的方法,但在网上你能找到很多其他的文章。
OurpathisgeneratedbyrepeatedlygoingthroughouropenlistandchoosingthesquarewiththelowestFscore.Thisprocesswillbedescribedinmoredetailabitfurtherinthearticle.Firstlet'slookmorecloselyathowwecalculatetheequation.
我们需要的路径是这样生成的:
反复的遍历开放列表,选择具有最小F值的方块。
这个过程在本文稍后会详细描述。
先让我们看看如何计算前面提到的等式。
Asdescribedabove,Gisthemovementcosttomovefromthestartingpointtothegivensquareusingthepathgeneratedtogetthere.Inthisexample,wewillassignacostof10toeachhorizontalorverticalsquaremoved,andacostof14foradiagonalmove.Weusethesenumbersbecausetheactualdistancetomovediagonallyisthesquarerootof2(don'tbescared),orroughly1.414timesthecostofmovinghorizontallyorvertically.Weuse10and14forsimplicity'ssake.Theratioisaboutright,andweavoidhavingtocalculatesquarerootsandweavoiddecimals.Thisisn'tjustbecausewearedumbanddon'tlikemath.Usingwholenumbersliketheseisalotfasterforthecomputer,too.Asyouwillsoonfindout,pathfindingcanbeveryslowifyoudon'tuseshortcutslikethese.
如上所述,G是经由到达它的路径,从开始点到给定方块的移动代价。
在本例中,我们为每个水平/垂直的移动指定代价为10,而斜角的移动代价为14。
我们使用这些值,因为斜角移动的实际距离是2的平方根(别害怕),或者大概1.414倍的水平/垂直的移动代价。
出于简化的目的使用了10和14。
比例大致是正确的,而我们却避免了方根和小数的计算。
倒不是我们没有能力做或者不喜欢数学。
使用这些数字也能让计算更快一些。
以后你就会发现,如果不使用这些技巧,寻路的计算非常慢。
SincewearecalculatingtheGcostalongaspecificpathtoagivensquare,thewaytofigureouttheGcostofthatsquareistotaketheGcostofitsparent,andthenadd10or14dependingonwhetheritisdiagonalororthogonal(non-diagonal)fromthatparentsquare.Theneedforthismethodwillbecomeapparentalittlefurtheroninthisexample,aswegetmorethanonesquareawayfromthestartingsquare.
既然我们沿着到达给定方块的路径来计算G的值,找出那个方块的G值的方法就是找到其父亲的G值,再加上10或者14而得,这依赖于他处于其父亲的斜角或者直角(非斜角)而定。
这在本例后面会更加清晰,随着我们从开始点离开而得到更多的方块。
Hcanbeestimatedinavarietyofways.ThemethodweusehereiscalledtheManhattanmethod,whereyoucalculatethetotalnumberofsquaresmovedhorizontallyandverticallytoreachthetargetsquarefromthecurrentsquare,ignoringdiagonalmovement.Wethenmultiplythetotalby10.ThisiscalledtheManhattanmethodbecauseit'slikecalculatingthenumberofcityblocksfromoneplacetoanother,whereyoucan'tcutacrosstheblockdiagonally.Importantly,whencalculatingH,weignoreanyinterveningobstacles.Thisisanestimateoftheremainingdistance,nottheactualdistance,whichiswhyit'scalledtheheuristic.Wanttoknowmore?
Youcanfindequationsandadditionalnotesonheuristicshere.
H能通过多种方法估算。
我们这里用到的方法叫做Manhattan方法,计算从当前方块经过水平/垂直移动而到达目标方块的方块总数。
然后将总数乘以10。
这种方法之所以叫做Manhattan方法,因为他很象计算从一个地点到达另一个地点的城市街区数量计算,此时你不能斜向的穿越街区。
重要的是,当计算H的时候,要忽略任何路径中的障碍。
这是一个对剩余距离的估算值,而不是实际值,这就是试探法的称谓由来。
想知道更多?
关于试探法的更多说明在这里。
FiscalculatedbyaddingGandH.Theresultsofthefirststepinoursearchcanbeseenintheillustrationbelow.TheF,G,andHscoresarewrittenineachsquare.Asisindicatedinthesquaretotheimmediaterightofthestartingsquare,Fisprintedinthetopleft,Gisprintedinthebottomleft,andHisprintedinthebottomright.
G和H相加就算出了F。
第一步搜索的结果见下图的描述。
F,G