Astar算法

本文介绍了A*算法的基本概念和工作原理,包括搜索区域的简化、路径排序、搜索过程及A*算法的总结。文章通过实例展示了如何从起点A找到终点B的最短路径,解释了G、H和F值的计算,以及如何通过比较F值选择最优路径。通过这个过程,最终找到从A到B的路径,并阐述了如何确定路径。
摘要由CSDN通过智能技术生成

转自:https://www.gamedev.net/articles/programming/artificial-intelligence/a-pathfinding-for-beginners-r2003/

简介:搜索区域

让我们假设我们有人想要从A点到达B点。让我们假设一条墙将这两点分开。这在下面说明,绿色是起点A,红色是终点B,蓝色填充的正方形是两者之间的墙。

                                              

您应该注意的第一件事是我们将搜索区域划分为方形网格。正如我们在这里所做的那样,简化搜索区域是寻路的第一步。这种特殊方法将我们的搜索区域缩小为简单的二维数组。数组中的每个项目代表网格上的一个正方形,其状态记录为可通过或不可通过。通过确定从A到B应该采取哪些方格来找到路径。一旦找到路径,我们的人就从一个方格的中心移动到下一个方格的中心,直到达到目标。

这些中心点称为“节点”。当您在其他地方阅读有关寻路的信息时,您会经常看到有人讨论节点。为什么不把它们称为方块?因为可以将寻路区域划分为方形以外的其他区域。它们可以是矩形,六边形,三角形或任何形状。节点可以放置在形状内的任何位置 - 中心或沿边缘,或其他任何地方。然而,我们正在使用这个系统,因为它是最简单的。

开始搜索(Starting the Search)

一旦我们把搜寻区域简化为一组可以量化的节点后,就像上面做的一样,我们下一步要做的便是查找最短路径。在 A* 中,我们从起点开始,检查其相邻的方格,然后向四周扩展,直至找到目标。

我们这样开始我们的寻路旅途:

1.       从起点 A 开始,并把它就加入到一个由方格组成的 open list( 开放列表 ) 中。这个 open list 有点像是一个购物单。当然现在 open list 里只有一项,它就是起点 A ,后面会慢慢加入更多的项。 Open list 里的格子是路径可能会是沿途经过的,也有可能不经过。基本上 open list 是一个待检查的方格列表。

2.       查看与起点 A 相邻的方格 ( 忽略其中墙壁所占领的方格,河流所占领的方格及其他非法地形占领的方格 ) ,把其中可走的 (walkable) 或可到达的 (reachable) 方格也加入到 open list 中。把起点 A 设置为这些方格的父亲 (parent node 或 parent square) 。当我们在追踪路径时,这些父节点的内容是很重要的。稍后解释。

3.       把 A 从 open list 中移除,加入到 close list( 封闭列表 ) 中, close list 中的每个方格都是现在不需要再关注的。

如下图所示,深绿色的方格为起点,它的外框是亮蓝色,表示该方格被加入到了 close list 。与它相邻的黑色方格是需要被检查的,他们的外框是亮绿色。每个黑方格都有一个灰色的指针指向他们的父节点,这里是起点 A 。

                                                                             

下一步,我们需要从 open list 中选一个与起点 A 相邻的方格,按下面描述的一样或多或少的重复前面的步骤。但是到底选择哪个方格好呢?具有最小 F 值的那个。

路径排序(Path Sorting)

计算出组成路径的方格的关键是下面这个等式:

F = G + H

这里,

G = 从起点 A 移动到指定方格的移动代价,沿着到达该方格而生成的路径。

H = 从指定的方格移动到终点 B 的估算成本。这个通常被称为试探法,有点让人混淆。为什么这么叫呢,因为这是个猜测。直到我们找到了路径我们才会知道真正的距离,因为途中有各种各样的东西 ( 比如墙壁,水等 ) 。本教程将教你一种计算 H 的方法,你也可以在网上找到其他方法。

我们的路径是这么产生的:反复遍历 open list ,选择 F 值最小的方格。这个过程稍后详细描述。我们还是先看看怎么去计算上面的等式。

如上所述, G 是从起点A移动到指定方格的移动代价。在本例中,横向和纵向的移动代价为 10 ,对角线的移动代价为 14 。之所以使用这些数据,是因为实际的对角移动距离是 2 的平方根,或者是近似的 1.414 倍的横向或纵向移动代价。使用 10 和 14 就是为了简单起见。比例是对的,我们避免了开放和小数的计算。这并不是我们没有这个能力或是不喜欢数学。使用这些数字也可以使计算机更快。稍后你便会发现,如果不使用这些技巧,寻路算法将很慢。

 

既然我们是沿着到达指定方格的路径来计算 G 值,那么计算出该方格的 G 值的方法就是找出其父亲的 G 值,然后按父亲是直线方向还是斜线方向加上 10 或 14 。随着我们离开起点而得到更多的方格,这个方法会变得更加明朗。

 

有很多方法可以估算 H 值。这里我们使用 Manhattan 方法,计算从当前方格横向或纵向移动到达目标所经过的方格数,忽略对角移动,然后把总数乘以 10 。之所以叫做 Manhattan 方法,是因为这很像统计从一个地点到另一个地点所穿过的街区数,而你不能斜向穿过街区。重要的是,计算 H 是,要忽略路径中的障碍物。这是对剩余距离的估算值,而不是实际值,因此才称为试探法。

 

把 G 和 H 相加便得到 F 。我们第一步的结果如下图所示。每个方格都标上了 F , G , H 的值,就像起点右边的方格那样,左上角是 F ,左下角是 G ,右下角是 H 。

                                          

好,现在让我们看看其中的一些方格。在标有字母的方格, G = 10 。这是因为水平方向从起点到那里只有一个方格的距离。与起点直接相邻的上方,下方,左方的方格的 G 值都是 10 ,对角线的方格 G 值都是 14 。

 

H 值通过估算起点于终点 ( 红色方格 ) 的 Manhattan 距离得到,仅作横向和纵向移动,并且忽略沿途的墙壁。使用这种方式,起点右边的方格到终点有 3 个方格的距离,因此 H = 30 。这个方格上方的方格到终点有 4 个方格的距离 ( 注意只计算横向和纵向距离 ) ,因此 H = 40 。对于其他的方格,你可以用同样的方法知道 H 值是如何得来的。

 

每个方格的 F 值,再说一次,直接把 G 值和 H 值相加就可以了。

继续搜索(Continuing the Search)

为了继续搜索,我们从 open list 中选择 F 值最小的 ( 方格 ) 节点,然后对所选择的方格作如下操作:

4.       把它从 open list 里取出,放到 close list 中。

5.       检查所有与它相邻的方格,忽略其中在 close list 中或是不可走 (unwalkable) 的方格 ( 比如墙,水,或是其他非法地形 ) ,如果方格不在open lsit 中,则把它们加入到 open list 中。

把我们选定的方格设置为这些新加入的方格的父亲。

6.       如果某个相邻的方格已经在 open list 中,则检查这条路径是否更优,也就是说经由当前方格 ( 我们选中的方格 ) 到达那个方格是否具有更小的 G 值。如果没有,不做任何操作。

相反,如果 G 值更小,则把那个方格的父亲设为当前方格 ( 我们选中的方格 ) ,然后重新计算那个方格的 F 值和 G 值。如果你还是很混淆,请参考下图。

                                          

这一次,当我们检查相邻的方块时,我们发现右边的那个是一个墙方块,所以我们忽略它。对于正好在上面的那个也是如此。我们也忽略了墙下方的广场。为什么?因为你不能直接从当前的广场到达那个广场,而不会越过附近墙壁的角落。你真的需要先下去,然后转移到那个广场,在这个过程中转移。(注意:关于切角的这条规则是可选的。它的使用取决于节点的放置方式。)

剩下五个正方形。当前方块下方的其他两个方块尚未在开放列表中,因此我们添加它们,当前方块成为其父级。在其他三个正方形中,两个已经在闭合列表中(起始正方形,正好在当前正方形上方,在图中以蓝色突出显示),因此我们忽略它们。然后检查当前正方形左边的最后一个方格,看看如果你通过当前的方格到达那里,G得分是否更低。没有骰子。所以我们已经完成并准备好检查我们的开放列表中的下一个方块。

我们重复这个过程,直到我们将目标方块添加到关闭列表中,此时它看起来如下图所示。

                                     

请注意,起始方块下方的正方形两个方格的父方块已从上一个插图中更改。在G得分为28之前,指向它上方和右侧的方格。现在它得分为20,并指向它上方的正方形。这发生在我们的搜索过程中的某个地方,其中G分数被检查,并且使用新路径结果显示较低 - 因此父母被切换并且重新计算了G和F分数。虽然这个变化在这个例子中似乎并不重要,但是在很多可能的情况下,这种不断的检查会在确定目标的最佳路径方面产生重大影响。

那么我们如何确定路径呢?简单,只需从红色目标方块开始,然后按照箭头向后移动,从一个方格移动到其父级。这将最终带你回到起跑广场,这就是你的道路。它应该如下图所示。从起始广场A移动到目的地广场B只是从每个广场(节点)的中心移动到路径上的下一个广场的中心,直到到达目标。

                                      

A*算法总结(Summary of the A* Method)

Ok ,现在你已经看完了整个的介绍,现在我们把所有步骤放在一起:

1.         把起点加入 open list 。

2.         重复如下过程:

a.         遍历 open list ,查找 F 值最小的节点,把它作为当前要处理的节点。

b.         把这个节点移到 close list 。

c.         对当前方格的 8 个相邻方格的每一个方格?

◆     如果它是不可抵达的或者它在 close list 中,忽略它。否则,做如下操作。

◆     如果它不在 open list 中,把它加入 open list ,并且把当前方格设置为它的父亲,记录该方格的 F , G 和 H 值。

◆     如果它已经在 open list 中,检查这条路径 ( 即经由当前方格到达它那里 ) 是否更好,用 G 值作参考。更小的 G 值表示这是更好的路径。如果是这样,把它的父亲设置为当前方格,并重新计算它的 G 和 F 值。如果你的 open list 是按 F 值排序的话,改变后你可能需要重新排序。

d.         停止,当你

◆     把终点加入到了 open list 中,此时路径已经找到了,或者

◆     查找终点失败,并且 open list 是空的,此时没有路径。

3.         保存路径。从终点开始,每个方格沿着父节点移动直至起点,这就是你的路径。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值