A星算法详解

合集下载

A星算法详解范文

A星算法详解范文

A星算法详解范文A*算法是一种常用的启发式算法,多用于解决图问题。

它是一种综合了Dijkstra算法和贪心算法的算法,利用估算函数来接近最短路径,提高效率。

下面我们来详细介绍A*算法。

A*算法的核心思想是综合考虑两个值:实际路径长度g(n)和启发式函数预估路径长度h(n)。

实际路径长度是指从起始点到当前点的路径长度,启发式函数预估路径长度是指从当前点到目标点的路径长度。

基于这两个值,A*算法会在过程中选择总的路径长度(f(n)=g(n)+h(n))最小的点进行扩展。

A*算法的伪代码如下:1. 将起始点加入open列表,并将起始点的f(n)值设为0。

2. 当open列表不为空时:a. 从open列表中选择f(n)值最小的点,并将该点加入closed列表。

b.如果选择的点是目标点,则结束,返回路径。

c.对于选择的点的每一个相邻点:i. 如果相邻点不可通行或者已经在closed列表中,则忽略。

ii. 如果相邻点不在open列表中,则将其加入open列表,并更新相邻点的父节点为选择的点,并计算相邻点的f(n)值。

iii. 如果相邻点已经在open列表中,比较从当前选择的点到相邻点的实际路径长度是否小于之前计算的路径长度,如果是,则更新相邻点的父节点和f(n)值。

A*算法的关键在于如何选择合适的启发式函数。

一个好的启发式函数应该尽量准确地估计从当前点到目标点的路径长度。

启发式函数常用的有以下几种形式:1.曼哈顿距离:启发式函数的值为当前点到目标点在格子网格中的曼哈顿距离,即横向和纵向的距离之和。

2.欧几里得距离:启发式函数的值为当前点到目标点的欧几里得距离,即两点之间的直线距离。

3.切比雪夫距离:启发式函数的值为当前点到目标点在格子网格中的切比雪夫距离,即横向和纵向的距离中最大的距离。

4.对角线距离:启发式函数的值为当前点到目标点在格子网格中的对角线距离,即两点之间的最短距离。

A*算法的优点是可以找到最短路径,而且在启发式函数设计合理的情况下,能够较快地找到最优解。

A星算法

A星算法


估价值h(n)<= n到目标节点的距离实际值,这种情况下, 搜索的点数多,搜索范围大,效率低。但能得到最优解。
如果 估价值>实际值,搜索的点数少,搜索范围小,效率高 ,但丌能保证得到最优解 PPT DESIGN
常见估价函数
(1)曼哈顿距离: 就是在欧几里德空间的固定直角坐标系上两点所形成的线 段对轴产生的投影的距离总和,例如在平面上,坐标(x1,y1) 的点P1不坐标(x2, y2)的点P2的曼哈顿距离为:|x1 - x2| + |y1 - y2|。 (2)欧氏距离: 它是在m维空间中两个点之间的真实距离。在二维和三维 空间中的欧氏距离的就是两点之间的距离。例如在平面上,坐 标(x1,y1)的点P1不坐标(x2, y2)的点P2的欧氏距离为: sqrt((x1-x2)^2+(y1-y2)^2 )。 (3)切比雪夫距离: 是两个向量之间各分量差值的最大值。例如在平面上,坐 标(x1, y1)的点P1不坐标(x2, y2)的点P2的切比雪夫距离 为:max(|x1 - x2| , |y1 - y2|) PPT DESIGN
【2】/page/resources/_/technical/artificialintelligence/a-pathfinding-for-beginners-r2003
PPT DESIGN
1,把起始格添加到开启列表。 2,重复如下的工作: a) 寻找开启列表中F值最低的格子。我们称它为当前格。
b) 把它切换到关闭列表。
c) 对相邻的格中的每一个? * 如果它丌可通过戒者已经在关闭列表中,略过它。反之如下。 * 如果它丌在开启列表中,把它添加迚去。把当前格作为这一格的父节点。记录 这一格的F,G,和H值。 * 如果它已经在开启列表中,用G值为参考检查新的路径是否更好。更低的G值 意味着更好的路径。如果是这样,就把这一格的父节点改成当前格,并且重新计算这一 格的G和F值。如果你保持你的开启列表按F值排序,改变之后你可能需要重新对开启列 表排序。 d) 停止,当你 * 把目标格添加迚了关闭列表(注解),这时候路径被找到,戒者

人工智能A星算法

人工智能A星算法

人工智能A星算法
人工智能A星算法(A* Algorithm)是一种启发式算法,它能够解决从一个起始点到特定终点的最短路径问题。

该算法是利用基于启发式的算法和最优子结构性质,该算法在空间中生成了一条最佳路径,既可以简单而又可靠。

A*算法通过评估每条路径的风险和代价,来确定最佳路径。

对于一个节点,算法将图上的所有可能路径的代价总和折算成一个“分数”,把这些“分数”比较,选择最低分的路径为最优路径。

(1)定义一个空间,在这个空间中有起点到终点的路径,并且定义一些实体:路点、障碍物、起点、终点等;
(2)将起点放入开放列表,开始;
(3)从开放列表中取出一个节点(称作当前节点),检查是否为终点,如果是,结束,如果不是,将当前节点放入关闭列表;
(4)在开放列表中寻找临近节点,将临近节点放入开放列表,并对每一个节点计算从起点到该节点的代价F,该代价由起点到当前节点的距离G和该节点距离终点的估价H之和;
(5)重复以上步骤,直到从开放列表中取出的节点是终点;
(6)返回最佳路径。

a星算法栅格大小 -回复

a星算法栅格大小 -回复

a星算法栅格大小-回复A*算法栅格大小(Grid Size):优化路径规划问题的关键因素引言:在实际生活中,我们经常面临需要找到最优路径的问题,比如在城市中规划最短的驾驶路线,或者在机器人路径规划中找到最节省能量的路径。

为了解决这类问题,A*(A-star)算法被广泛应用。

而A*算法中栅格大小的选择,直接影响到算法的运行效率和结果的准确性。

本文将分步骤详细回答关于A*算法栅格大小问题,帮助读者更好地理解该算法并能灵活应用。

第一步:什么是A*算法?A*算法是一种启发式搜索算法,用于在图形地图或网络中寻找最短路径。

它综合考虑了路径长度和启发函数(估计距离)来选择下一步的移动方向,以达到更高的搜索效率。

第二步:A*算法中的栅格大小是什么意思?在应用A*算法时,地图或网络被划分成多个小方格,每个方格被称为一个栅格。

栅格的大小决定了图形地图或网络的分辨率,直接影响到A*算法的搜索过程和搜索结果。

第三步:如何选择合适的栅格大小?1. 如何确定栅格数:栅格数可以通过将地图或网络的长度和宽度除以栅格的大小得到。

例如,如果地图的长度为100米,宽度为100米,我们选择10x10米的栅格大小,则地图将被划分成10x10个栅格。

2. 如何选择合适的栅格大小:栅格大小的选择应该综合考虑以下几个因素:a. 地图或网络的规模:大地图或网络通常需要较大的栅格,以便更好地表示地图信息,并存储和处理更多的栅格数据。

b. 搜索的精度要求:如果需要精确计算最优路径的长度,应选择较小的栅格大小。

c. 计算资源限制:较大的栅格大小可能会导致更高的计算复杂性和更长的计算时间。

如果计算资源有限,可以选择较大的栅格来降低计算开销。

d. 环境特征:如果地图或网络中存在窄小的路径或拥挤的区域,应选择较小的栅格以更准确地表示这些细节。

第四步:栅格大小对A*算法的影响1. 增加栅格大小的优点:a. 减少计算开销:使用较大的栅格可以降低搜索空间的规模,从而减少计算开销,提高搜索效率。

a星算法的原理

a星算法的原理

a星算法的原理A*算法的原理A*算法是一种常用的寻路算法,用于在图形化的环境中找到从起点到目标点的最短路径。

它结合了Dijkstra算法和贪心算法的优点,能够高效地找到最佳路径。

A*算法的核心思想是通过启发式函数来评估每个节点的价值,以选择下一个要探索的节点。

这个启发式函数通常被称为估价函数,它用来估计从当前节点到目标节点的距离。

A*算法会维护一个开放列表和一个关闭列表,来存储待探索的节点和已经探索过的节点。

A*算法的具体步骤如下:1. 初始化:将起点加入开放列表,并将其G值(起点到起点的实际代价)设置为0。

2. 进入循环:如果开放列表不为空,则继续执行循环。

3. 寻找最佳节点:从开放列表中选择估价函数值最小的节点作为当前节点,并将其移出开放列表,加入关闭列表。

4. 判断是否达到目标:如果当前节点是目标节点,则路径已找到,终止算法。

5. 遍历相邻节点:遍历当前节点的所有相邻节点。

6. 更新节点:计算每个相邻节点的G值和H值(估价函数值)。

如果该节点不在开放列表中,则将其加入开放列表,并更新其父节点为当前节点。

7. 重新排序开放列表:按照节点的F值(G值加上H值)重新排序开放列表,以便下一次循环时选择估价函数值最小的节点。

8. 继续循环:回到步骤2,继续执行循环。

9. 生成路径:当目标节点被加入关闭列表时,路径已找到。

通过回溯每个节点的父节点,从目标节点到起点生成最短路径。

A*算法的优势在于它能够根据启发式函数快速找到接近最佳路径的节点,从而减少了搜索的时间和空间复杂度。

启发式函数的选择对算法的性能影响很大,一个好的启发式函数能够提高算法的效率。

然而,A*算法也存在一些限制。

首先,如果启发式函数不是一致的(也称为单调的),则无法保证找到的路径是最短路径。

其次,A*算法在遇到图形中存在大量障碍物或者复杂的地形时,可能会产生大量的节点扩展,导致算法效率下降。

为了解决这些问题,研究者们提出了各种改进的A*算法,例如IDA*算法、Jump Point Search算法等。

a星算法 贝塞尔曲线平滑处理

a星算法 贝塞尔曲线平滑处理

a星算法贝塞尔曲线平滑处理
A*算法(A-star algorithm)是一种常用于图搜索和路径规划的算法。

它通过在图中沿着最有可能的路径搜索目标来找到最短路径。

贝塞尔曲线平滑处理(Bezier curve smoothing)是一种用于将曲线变得更加平滑的方法。

它使用贝塞尔曲线的特性,通过调节控制点来调整曲线的形状,从而实现平滑效果。

在路径规划中,可以将A*算法和贝塞尔曲线平滑处理结合起来,以使路径在地图中更加平滑和自然。

具体步骤如下:
1. 使用A*算法计算出起点到终点的最短路径。

2. 将最短路径的关键点作为贝塞尔曲线的控制点。

3. 通过调整控制点的位置和权重,使贝塞尔曲线与最短路径更好地拟合。

4. 使用贝塞尔曲线生成平滑路径,并将其作为最终路径。

这样做可以消除路径中的尖角和突变,使得路径更加平滑和易于理解。

同时,通过调整贝塞尔曲线的权重和控制点,还可以实现路径的进一步优化和调整,以适应具体的需求。

a星算法的原理(一)

a星算法的原理(一)

a星算法的原理(一)A星算法1. 引言A星算法(A*算法)是一种常用的路径搜索算法,用于在图形上找到两个节点之间的最短路径。

该算法通过在搜索过程中利用启发式函数(heuristic)来评估每个节点的可能成本,以决定搜索哪个节点。

2. 原理概述A星算法基于图搜索算法,通过维护一个优先级队列来选择下一个要扩展的节点。

具体来说,算法按照优先级从高到低的顺序遍历节点,直到找到目标节点或队列为空。

3. 节点评估为了选择下一个要扩展的节点,A星算法使用了一个评估函数。

该函数将节点的价值估计为从起始节点到目标节点的实际成本加上启发式函数的估计值。

4. 启发式函数启发式函数是A星算法的核心。

它根据当前节点和目标节点的位置计算节点的估计成本。

这个估计成本应该是乐观的,即不会低估实际成本。

常用的启发式函数包括曼哈顿距离和欧式距离。

4.1 曼哈顿距离曼哈顿距离是通过水平和垂直距离计算两个点之间的距离。

对于二维平面上的点A(x1, y1)和点B(x2, y2),曼哈顿距离的计算公式为:|x1 - x2| + |y1 - y2|4.2 欧式距离欧式距离是通过直线距离计算两个点之间的距离。

对于二维平面上的点A(x1, y1)和点B(x2, y2),欧式距离的计算公式为:sqrt((x1-x2)^2 + (y1-y2)^2)5. 算法步骤A星算法的具体步骤如下: 1. 初始化起始节点和目标节点。

2. 将起始节点添加到待扩展节点的优先级队列中,其中其估计成本为0。

3. 循环执行以下步骤直到找到目标节点或队列为空: - 从优先级队列中选择估计成本最低的节点。

- 如果该节点是目标节点,算法结束。

- 否则,将该节点标记为已访问,并将其邻居节点添加到优先级队列中。

4. 如果队列为空且未找到目标节点,则表示目标节点无法达到。

6. 优缺点A星算法的优点在于它可以快速找到最短路径,并且能在找到路径之前通过启发式函数进行剪枝,减少搜索空间。

astar(a星)算法(精)

astar(a星)算法(精)

A*算法原理简介A*(A-Star)算法是一种静态路网中求解最短路最有A star算法在静态路网中的应用效的方法。

公式表示为: f(n)=g(n)+h(n),其中f(n) 是节点n从初始点到目标点的估价函数,g(n) 是在状态空间中从初始节点到n节点的实际代价,h(n)是从n到目标节点最佳路径的估计代价。

保证找到最短路径(最优解的)条件,关键在于估价函数h(n)的选取:估价值h(n)<= n到目标节点的距离实际值,这种情况下,搜索的点数多,搜索范围大,效率低。

但能得到最优解。

如果估价值>实际值, 搜索的点数少,搜索范围小,效率高,但不能保证得到最优解。

估价值与实际值越接近估价函数取得就越好例如对于几何路网来说,可以取两节点间欧几理德距离(直线距离)做为估价值,即f=g(n)+sqrt((dx-nx)*(dx-nx)+(dy-ny)*(dy-ny));这样估价函数f在g值一定的情况下,会或多或少的受估价值h的制约,节点距目标点近,h值小,f值相对就小,能保证最短路的搜索向终点的方向进行。

明显优于Dijstra算法的毫无无方向的向四周搜索。

conditions of heuristicOptimistic (must be less than or equal to the real cost)As close to the real cost as possible详细内容主要搜索过程伪代码如下:创建两个表,OPEN表保存所有已生成而未考察的节点,CLOSED表中记录已访问过的节点。

算起点的估价值;将起点放入OPEN表;while(OPEN!=NULL){从OPEN表中取估价值f最小的节点n;if(n节点==目标节点){break;}for(当前节点n 的每个子节点X){算X的估价值;if(X in OPEN){if( X的估价值小于OPEN表的估价值 ){把n设置为X的父亲;更新OPEN表中的估价值; //取最小路径的估价值}}if(X inCLOSE) {if( X的估价值小于CLOSE表的估价值 ){把n设置为X的父亲;更新CLOSE表中的估价值;把X节点放入OPEN //取最小路径的估价值}}if(X not inboth){把n设置为X的父亲;求X的估价值;并将X插入OPEN表中; //还没有排序}}//end for将n节点插入CLOSE表中;按照估价值将OPEN表中的节点排序; //实际上是比较OPEN表内节点f的大小,从最小路径的节点向下进行。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

初识A*算法写这篇文章的初衷是应一个网友的要求,当然我也发现现在有关人工智能的中文站点实在太少,我在这里抛砖引玉,希望大家都来热心的参与。

还是说正题,我先拿A*算法开刀,是因为A*在游戏中有它很典型的用法,是人工智能在游戏中的代表。

A*算法在人工智能中是一种典型的启发式搜索算法,为了说清楚A*算法,我看还是先说说何谓启发式算法。

一、何谓启发式搜索算法在说它之前先提提状态空间搜索。

状态空间搜索,如果按专业点的说法就是将问题求解过程表现为从初始状态到目标状态寻找这个路径的过程。

通俗点说,就是在解一个问题时,找到一条解题的过程可以从求解的开始到问题的结果(好象并不通俗哦)。

由于求解问题的过程中分枝有很多,主要是求解过程中求解条件的不确定性,不完备性造成的,使得求解的路径很多这就构成了一个图,我们说这个图就是状态空间。

问题的求解实际上就是在这个图中找到一条路径可以从开始到结果。

这个寻找的过程就是状态空间搜索。

常用的状态空间搜索有深度优先和广度优先。

广度优先是从初始状态一层一层向下找,直到找到目标为止。

深度优先是按照一定的顺序前查找完一个分支,再查找另一个分支,以至找到目标为止。

这两种算法在数据结构书中都有描述,可以参看这些书得到更详细的解释。

前面说的广度和深度优先搜索有一个很大的缺陷就是他们都是在一个给定的状态空间中穷举。

这在状态空间不大的情况下是很合适的算法,可是当状态空间十分大,且不预测的情况下就不可取了。

他的效率实在太低,甚至不可完成。

在这里就要用到启发式搜索了。

启发式搜索就是在状态空间中的搜索对每一个搜索的位置进行评估,得到最好的位置,再从这个位置进行搜索直到目标。

这样可以省略大量无畏的搜索路径,提到了效率。

在启发式搜索中,对位置的估价是十分重要的。

采用了不同的估价可以有不同的效果。

我们先看看估价是如何表示的。

启发中的估价是用估价函数表示的,如:f(n) = g(n) + h(n)其中f(n)是节点n的估价函数,g(n)实在状态空间中从初始节点到n节点的实际代价,h(n)是从n到目标节点最佳路径的估计代价。

在这里主要是h(n)体现了搜索的启发信息,因为g(n)是已知的。

如果说详细点,g(n)代表了搜索的广度的优先趋势。

但是当h(n)>>g(n)时,可以省略g(n),而提高效率。

这些就深了,不懂也不影响啦!我们继续看看何谓A*算法。

二、初识A*算法启发式搜索其实有很多的算法,比如:局部择优搜索法、最好优先搜索法等等。

当然A*也是。

这些算法都使用了启发函数,但在具体的选取最佳搜索节点时的策略不同。

象局部择优搜索法,就是在搜索的过程中选取“最佳节点”后舍弃其他的兄弟节点,父亲节点,而一直得搜索下去。

这种搜索的结果很明显,由于舍弃了其他的节点,可能也把最好的节点都舍弃了,因为求解的最佳节点只是在该阶段的最佳并不一定是全局的最佳。

最好优先就聪明多了,他在搜索时,便没有舍弃节点(除非该节点是死节点),在每一步的估价中都把当前的节点和以前的节点的估价值比较得到一个“最佳的节点”。

这样可以有效的防止“最佳节点”的丢失。

那么A*算法又是一种什么样的算法呢?其实A*算法也是一种最好优先的算法。

只不过要加上一些约束条件罢了。

由于在一些问题求解时,我们希望能够求解出状态空间搜索的最短路径,也就是用最快的方法求解问题,A*就是干这种事情的!我们先下个定义,如果一个估价函数可以找出最短的路径,我们称之为可采纳性。

A*算法是一个可采纳的最好优先算法。

A*算法的估价函数可表示为:f'(n) = g'(n) + h'(n)这里,f'(n)是估价函数,g'(n)是起点到终点的最短路径值,h'(n)是n到目标的最断路经的启发值。

由于这个f'(n)其实是无法预先知道的,所以我们用前面的估价函数f(n)做近似。

g(n)代替g'(n),但g(n)>=g'(n)才可(大多数情况下都是满足的,可以不用考虑),h(n)代替h'(n),但h(n)<=h'(n)才可(这一点特别的重要)。

可以证明应用这样的估价函数是可以找到最短路径的,也就是可采纳的。

我们说应用这种估价函数的最好优先算法就是A*算法。

哈!你懂了吗?肯定没懂!接着看!举一个例子,其实广度优先算法就是A*算法的特例。

其中g(n)是节点所在的层数,h(n)=0,这种h(n)肯定小于h'(n),所以由前述可知广度优先算法是一种可采纳的。

实际也是。

当然它是一种最臭的A*算法。

再说一个问题,就是有关h(n)启发函数的信息性。

h(n)的信息性通俗点说其实就是在估计一个节点的值时的约束条件,如果信息越多或约束条件越多则排除的节点就越多,估价函数越好或说这个算法越好。

这就是为什么广度优先算法的那么臭的原因了,谁叫它的h(n)=0,一点启发信息都没有。

但在游戏开发中由于实时性的问题,h(n)的信息越多,它的计算量就越大,耗费的时间就越多。

就应该适当的减小h(n)的信息,即减小约束条件。

但算法的准确性就差了,这里就有一个平衡的问题。

可难了,这就看你的了!好了我的话也说得差不多了,我想你肯定是一头的雾水了,其实这是写给懂A*算法的同志看的。

哈哈!你还是找一本人工智能的书仔细看看吧!我这几百字是不足以将A*算法讲清楚的。

只是起到抛砖引玉的作用,希望大家热情参与嘛!预知A*算法的应用,请看姊妹篇《深入A*算法》。

Sunway深入A*算法一、前言在这里我将对A*算法的实际应用进行一定的探讨,并且举一个有关A*算法在最短路径搜索的例子。

值得注意的是这里并不对A*的基本的概念作介绍,如果你还对A*算法不清楚的话,请看姊妹篇《初识A*算法》。

这里所举的例子是参考AMIT主页中的一个源程序,使用这个源程序时,应该遵守一定的公约。

二、A*算法的程序编写原理我在《初识A*算法》中说过,A*算法是最好优先算法的一种。

只是有一些约束条件而已。

我们先来看看最好优先算法是如何编写的吧。

如图有如下的状态空间:(起始位置是A,目标位置是P,字母后的数字表示节点的估价值)搜索过程中设置两个表:OPEN和CLOSED。

OPEN表保存了所有已生成而未考察的节点,CLOSED表中记录已访问过的节点。

算法中有一步是根据估价函数重排OPEN表。

这样循环中的每一步只考虑OPEN表中状态最好的节点。

具体搜索过程如下:1)初始状态:OPEN=[A5];CLOSED=[];2)估算A5,取得搜有子节点,并放入OPEN表中;OPEN=[B4,C4,D6];CLOSED=[A5]3)估算B4,取得搜有子节点,并放入OPEN表中;OPEN=[C4,E5,F5,D6];CLOSED=[B4,A5]4)估算C4;取得搜有子节点,并放入OPEN表中;OPEN=[H3,G4,E5,F5,D6];CLOSED=[C4,B4,A5]5)估算H3,取得搜有子节点,并放入OPEN表中;OPEN=[O2,P3,G4,E5,F5,D6];CLOSED=[H3,C4,B4,A5]6)估算O2,取得搜有子节点,并放入OPEN表中;OPEN=[P3,G4,E5,F5,D6];CLOSED=[O2,H3,C4,B4,A5]7)估算P3,已得到解;看了具体的过程,再看看伪程序吧。

算法的伪程序如下:Best_First_Search(){Open = [起始节点];Closed = [];while (Open表非空){从Open中取得一个节点X,并从OPEN表中删除。

if (X是目标节点){求得路径PATH;返回路径PATH;}for (每一个X的子节点Y){if (Y不在OPEN表和CLOSE表中){求Y的估价值;并将Y插入OPEN表中;}//还没有排序else if (Y在OPEN表中){if (Y的估价值小于OPEN表的估价值)更新OPEN表中的估价值;}else //Y在CLOSE表中{if (Y的估价值小于CLOSE表的估价值){更新CLOSE表中的估价值;从CLOSE表中移出节点,并放入OPEN表中;}}将X节点插入CLOSE表中;按照估价值将OPEN表中的节点排序;}//end for}//end while}//end func啊!伪程序出来了,写一个源程序应该不是问题了,依葫芦画瓢就可以。

A*算法的程序与此是一样的,只要注意估价函数中的g(n)的h(n)约束条件就可以了。

不清楚的可以看看《初识A*算法》。

好了,我们可以进入另一个重要的话题,用A*算法实现最短路径的搜索。

在此之前你最好认真的理解前面的算法。

不清楚可以找我。

我的Email在文章尾。

三、用A*算法实现最短路径的搜索在游戏设计中,经常要涉及到最短路径的搜索,现在一个比较好的方法就是用A*算法进行设计。

他的好处我们就不用管了,反正就是好!^_*注意下面所说的都是以ClassAstar这个程序为蓝本,你可以在这里下载这个程序。

这个程序是一个完整的工程。

里面带了一个EXE文件。

可以先看看。

先复习一下,A*算法的核心是估价函数f(n),它包括g(n)和h(n)两部分。

g(n)是已经走过的代价,h(n)是n到目标的估计代价。

在这个例子中g(n)表示在状态空间从起始节点到n节点的深度,h(n)表示n节点所在地图的位置到目标位置的直线距离。

啊!一个是状态空间,一个是实际的地图,不要搞错了。

再详细点说,有一个物体A,在地图上的坐标是(xa,ya),A所要到达的目标b的坐标是(xb,yb)。

则开始搜索时,设置一个起始节点1,生成八个子节点2- 9 因为有八个方向。

如图:仔细看看节点1、9、17的g(n)和h(n)是怎么计算的。

现在应该知道了下面程序中的f(n)是如何计算的吧。

开始讲解源程序了。

其实这个程序是一个很典型的教科书似的程序,也就是说只要你看懂了上面的伪程序,这个程序是十分容易理解的。

不过他和上面的伪程序有一些的不同,我在后面会提出来。

先看搜索主函数:void AstarPathfinder::FindPath(int sx, int sy, int dx, int dy){NODE *Node, *BestNode;int TileNumDest;//得到目标位置,作判断用TileNumDest = TileNum(sx, sy);//生成Open和Closed表OPEN = ( NODE* )calloc(1,sizeof( NODE ));CLOSED=( NODE* )calloc(1,sizeof( NODE ));//生成起始节点,并放入Open表中Node=( NODE* )calloc(1,sizeof( NODE ));Node->g = 0;//这是计算h值// should really use sqrt().Node->h = (dx-sx)*(dx-sx) + (dy-sy)*(dy-sy);//这是计算f值,即估价值Node->f = Node->g+Node->h;Node->NodeNum = TileNum(dx, dy);Node->x = dx; Node->y = dy;// make Open List point to first nodeOPEN->NextNode=Node;for (;;){//从Open表中取得一个估价值最好的节点BestNode=ReturnBestNode();//如果该节点是目标节点就退出// if we've found the end, break and finish break;if (BestNode->NodeNum == TileNumDest)//否则生成子节点GenerateSuccessors(BestNode,sx,sy);}PATH = BestNode;}再看看生成子节点函数:void AstarPathfinder::GenerateSuccessors(NODE *BestNode, int dx, int dy) {int x, y;//哦!依次生成八个方向的子节点,简单!// Upper-Leftif ( FreeTile(x=BestNode->x-TILESIZE, y=BestNode->y-TILESIZE) )GenerateSucc(BestNode,x,y,dx,dy);// Upperif ( FreeTile(x=BestNode->x, y=BestNode->y-TILESIZE) )GenerateSucc(BestNode,x,y,dx,dy);// Upper-Rightif ( FreeTile(x=BestNode->x+TILESIZE, y=BestNode->y-TILESIZE) )GenerateSucc(BestNode,x,y,dx,dy);// Rightif ( FreeTile(x=BestNode->x+TILESIZE, y=BestNode->y) )GenerateSucc(BestNode,x,y,dx,dy);// Lower-Rightif ( FreeTile(x=BestNode->x+TILESIZE, y=BestNode->y+TILESIZE) )GenerateSucc(BestNode,x,y,dx,dy);// Lowerif ( FreeTile(x=BestNode->x, y=BestNode->y+TILESIZE) )GenerateSucc(BestNode,x,y,dx,dy);// Lower-Leftif ( FreeTile(x=BestNode->x-TILESIZE, y=BestNode->y+TILESIZE) )GenerateSucc(BestNode,x,y,dx,dy);// Leftif ( FreeTile(x=BestNode->x-TILESIZE, y=BestNode->y) )GenerateSucc(BestNode,x,y,dx,dy);}看看最重要的函数:void AstarPathfinder::GenerateSucc(NODE *BestNode,int x, int y, int dx, int dy){int g, TileNumS, c = 0;NODE *Old, *Successor;//计算子节点的 g 值// g(Successor)=g(BestNode)+cost of getting from BestNode to Successor g = BestNode->g+1;// identification purposesTileNumS = TileNum(x,y);//子节点再Open表中吗?// if equal to NULL then not in OPEN list, else it returns the Node in Oldif ( (Old=CheckOPEN(TileNumS)) != NULL ){//若在for( c = 0; c < 8; c++)// Add Old to the list of BestNode's Children (or Successors). if( BestNode->Child[c] == NULL )break;BestNode->Child[c] = Old;//比较Open表中的估价值和当前的估价值(只要比较g值就可以了)// if our new g value is < Old's then reset Old's parent to point to BestNodeif ( g < Old->g ){//当前的估价值小就更新Open表中的估价值Old->Parent = BestNode;Old->g = g;Old->f = g + Old->h;}}else//在Closed表中吗?// if equal to NULL then not in OPEN list, else it returns the Node in Oldif ( (Old=CheckCLOSED(TileNumS)) != NULL ){//若在for( c = 0; c< 8; c++)// Add Old to the list of BestNode's Children (or Successors). if ( BestNode->Child[c] == NULL )break;BestNode->Child[c] = Old;//比较Closed表中的估价值和当前的估价值(只要比较g值就可以了) // if our new g value is < Old's then reset Old's parent to point to BestNodeif ( g < Old->g ){//当前的估价值小就更新Closed表中的估价值Old->Parent = BestNode;Old->g = g;Old->f = g + Old->h;//再依次更新Old的所有子节点的估价值// Since we changed the g value of Old, we need// to propagate this new value downwards, i.e.// do a Depth-First traversal of the tree!PropagateDown(Old);}}//不在Open表中也不在Close表中else{//生成新的节点Successor = ( NODE* )calloc(1,sizeof( NODE ));Successor->Parent = BestNode;Successor->g = g;// should do sqrt(), but since we don't reallySuccessor->h = (x-dx)*(x-dx) + (y-dy)*(y-dy);// care about the distance but just which branch looksSuccessor->f = g+Successor->h;// better this should suffice. Anyayz it's faster.Successor->x = x;Successor->y = y;Successor->NodeNum = TileNumS;//再插入Open表中,同时排序。

相关文档
最新文档