A星算法经典
A_star算法(A算法经典译文)

GameRes游戏开发资源网 Amit's A star Page中译文译序这篇文章很适合A*算法的初学者,可惜网上没找到翻译版的。
本着好东西不敢独享的想法,也为了锻炼一下英文,本人译了这篇文章。
由于本人英文水平非常有限,六级考了两次加一块不超过370分,因此本译文难免存在问题。
不过也算是抛砖引玉,希望看到有更多的游戏开发方面的优秀译作出现,毕竟中文的优秀资料太少了,中国的游戏开发者的路不好走。
本人能力有限,译文中有小部分词句实在难以翻译,因此暂时保留英文原文放在译文中。
对于不敢确定翻译是否准确的词句,本人用圆括号保留了英文原文,读者可以对照着加以理解。
A*算法本身是很简单的,因此原文中并没有过多地讨论A*算法本身,而是花了较大的篇幅讨论了用于保存OPEN和CLOSED集的数据结构,以及A*算法的变种和扩展。
编程实现A*是简单的,读者可以用STL对本文中的伪代码加以实现(本人已花一天时间实验过基本的A*搜索)。
但是最重要的还是对A*本身的理解,这样才可以在自己的游戏中处理各种千变万化的情况。
翻译本文的想法产生于2006年5月,实际完成于2007年4月到6月,非常惭愧。
最后,本译文仅供交流和参考,对于因本译文放到网上而产生的任何问题,本人不负任何责任。
蔡鸿于南开大学软件学院2007年6月9日原文地址:/~amitp/GameProgramming/相关链接:/%7Eamitp/gameprog.html#Paths我们尝试解决的问题是把一个游戏对象(game object)从出发点移动到目的地。
路径搜索(Pathfinding)的目标是找到一条好的路径——避免障碍物、敌人,并把代价(燃料,时间,距离,装备,金钱等)最小化。
运动(Movement)的目标是找到一条路径并且沿着它行进。
把关注的焦点仅集中于其中的一种方法是可能的。
一种极端情况是,当游戏对象开始移动时,一个老练的路径搜索器(pathfinder)外加一个琐细的运动算法(movement algorithm)可以找到一条路径,游戏对象将会沿着该路径移动而忽略其它的一切。
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星算法求解八数码问题python

a星算法求解八数码问题python一、介绍八数码问题是一种经典的智力游戏,也是人工智能领域中的经典问题之一。
在这个问题中,有一个3×3的棋盘,上面摆着1至8这8个数字和一个空格,初始状态和目标状态都已知。
要求通过移动数字,将初始状态变换成目标状态。
其中空格可以和相邻的数字交换位置。
为了解决这个问题,我们可以使用A*算法。
本文将详细介绍如何用Python实现A*算法来求解八数码问题。
二、A*算法简介A*算法是一种启发式搜索算法,常用于寻找最短路径或最优解等问题。
它基于Dijkstra算法,并加入了启发式函数来加速搜索过程。
在A*算法中,每个节点都有两个估价值:g值和h值。
g值表示从起点到该节点的实际代价,h值表示从该节点到目标节点的估计代价。
启发式函数f(n) = g(n) + h(n) 表示从起点到目标节点的估计总代价。
A*算法采用优先队列来保存待扩展的节点,并按照f(n)值从小到大排序。
每次取出队头元素进行扩展,并将扩展出来的新节点按照f(n)值插入队列中。
当扩展出目标节点时,算法结束。
三、八数码问题的状态表示在八数码问题中,每个状态都可以表示为一个3×3的矩阵。
我们可以用一个一维数组来表示这个矩阵,其中0表示空格。
例如,初始状态可以表示为[2, 8, 3, 1, 6, 4, 7, 0, 5],目标状态可以表示为[1, 2, 3, 8, 0, 4, 7, 6, 5]。
四、A*算法求解八数码问题的步骤1.将初始状态加入优先队列中,并设置g值和h值为0。
2.从队头取出一个节点进行扩展。
如果该节点是目标节点,则搜索结束;否则,将扩展出来的新节点加入优先队列中。
3.对于每个新节点,计算g值和h值,并更新f(n)值。
如果该节点已经在优先队列中,则更新其估价值;否则,将其加入优先队列中。
4.重复第2步至第3步直到搜索结束。
五、Python实现以下是用Python实现A*算法求解八数码问题的代码:```import heapqimport copy# 目标状态goal_state = [1,2,3,8,0,4,7,6,5]# 启发式函数:曼哈顿距离def h(state):distance = 0for i in range(9):if state[i] == 0:continuerow = i // 3col = i % 3goal_row = (state[i]-1) // 3goal_col = (state[i]-1) % 3distance += abs(row - goal_row) + abs(col - goal_col)return distance# A*算法def A_star(start_state):# 初始化优先队列和已访问集合queue = []visited = set()# 将初始状态加入优先队列中,并设置g值和h值为0heapq.heappush(queue, (h(start_state), start_state, 0))while queue:# 取出队头元素进行扩展f, state, g = heapq.heappop(queue)# 如果该节点是目标节点,则搜索结束;否则,将扩展出来的新节点加入优先队列中。
A星算法求解旅行商问题(可打印修改)

int size = str_arr.length; int[] int_arr = new int[size];
for(int i = 0; i < size; i ++){ int_arr[i] = Integer.valueOf(str_arr[i]);
}
return int_arr; }
//获取所有路径中最短的路径 private int get_min_distance(){
FileInputStream fi = new FileInputStream(file);
InputStreamReader ir = new InputStreamReader(fi);
BufferedReader br = new BufferedReader(ir);
//------------------------------------
城市之间的距离:通过 n*n 矩阵 city_distance 表示,其中 n 表示城市的个数。编号为 k 的城市到各个城市之间的距离可以从第(k-1)行获取。
open 表:用队列表示,城市结点进入队列之前需要根据估计值 fvalue 按升序排列。
close 表:用向量表示。 搜索图:搜索图通过 open 表构建,将路径的编号保存在一个数组 id_list 中。 四、实验结果和分析 1、输入数据 第一行的数Байду номын сангаас 8 表示城市结点的个数,后面是一个 8*8 的数组,数组的值表示城市之 间的距离。任何一个结点到自身的距离是 0,数组中的第 0 行表示第 1 个城市到各个城市 之间的距离,其他的可类推。
Astar 算法求解旅行商问题
一、问题描述 一共有 n 个城市,某推销员从其中的一个城市 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-star algorithm)是一种常用于图搜索和路径规划的算法。
它通过在图中沿着最有可能的路径搜索目标来找到最短路径。
贝塞尔曲线平滑处理(Bezier curve smoothing)是一种用于将曲线变得更加平滑的方法。
它使用贝塞尔曲线的特性,通过调节控制点来调整曲线的形状,从而实现平滑效果。
在路径规划中,可以将A*算法和贝塞尔曲线平滑处理结合起来,以使路径在地图中更加平滑和自然。
具体步骤如下:
1. 使用A*算法计算出起点到终点的最短路径。
2. 将最短路径的关键点作为贝塞尔曲线的控制点。
3. 通过调整控制点的位置和权重,使贝塞尔曲线与最短路径更好地拟合。
4. 使用贝塞尔曲线生成平滑路径,并将其作为最终路径。
这样做可以消除路径中的尖角和突变,使得路径更加平滑和易于理解。
同时,通过调整贝塞尔曲线的权重和控制点,还可以实现路径的进一步优化和调整,以适应具体的需求。
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星算法的优点在于它可以快速找到最短路径,并且能在找到路径之前通过启发式函数进行剪枝,减少搜索空间。
A星算法中文详解

A星算法中文详解A*算法是一种图算法,用于找到从起始节点到目标节点的最短路径。
它是一种启发式算法,根据每个节点的估计成本来进行。
本文将详细介绍A*算法的原理、步骤和实现。
A* 算法的基本思想是在 Dijkstra 算法的基础上引入启发式函数,目的是在过程中尽量选择离目标节点更接近的路径。
启发式函数通常使用两个估计函数的和:g(n) 是从起始节点到当前节点的实际代价,h(n) 是当前节点到目标节点的估计代价。
通过评估 f(n) = g(n) + h(n) 的值,选择 f(n) 最小的节点作为下一步的节点。
这样,方向就会倾向于更接近目标节点的路径。
A*算法的步骤如下:1. 创建两个空集合:Open 集合和 Closed 集合。
Open 集合存储待考虑的节点,Closed 集合存储已经考虑过的节点。
2. 将起始节点添加到 Open 集合中,并初始化 g(n) 和 h(n) 的值。
3. 从 Open 集合中选择 f(n) 最小的节点作为当前节点,并将其移出 Open 集合,放入 Closed 集合中。
4.对当前节点的相邻节点进行遍历:- 如果相邻节点已经在 Closed 集合中,则忽略它。
- 如果相邻节点不在 Open 集合中,将其添加到 Open 集合,并计算g(n) 和 h(n) 的值。
- 如果相邻节点已经在 Open 集合中,计算经过当前节点到达相邻节点的 g(n) 值。
如果计算得到的 g(n) 值更小,则更新相邻节点的 g(n) 值。
5. 重复步骤 3 和 4,直到找到目标节点或者 Open 集合为空。
如果Open 集合为空且没有找到目标节点,则表示无法到达目标节点。
6.如果找到目标节点,可以通过回溯从目标节点到起始节点的路径。
路径上的节点可以通过每个节点的父节点指针找到。
以上就是A*算法的详细步骤。
A*算法的时间复杂度取决于启发式函数的选择和问题的规模。
通常情况下,A*算法的时间复杂度为O(b^d),其中b是分支因子,d是目标节点的最短路径长度。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
A*寻路初探 原文:Patrick Lester 翻译:Panic 2005年3月18日
原文出处:A* Pathfinding for Beginners
译者序 很久以前就知道了A*算法,但是从未认真读过相关的文章,也没有看过代码,只是脑子里有个模糊的概念。这次决定从头开始,研究一下这个被人推崇备至的简单方法,作为学习人工智能的开始。 这篇文章非常知名,国内应该有不少人翻译过它,我没有查找,觉得翻译本身也是对自身英文水平的锻炼。经过努力,终于完成了文档,也明白的A*算法的原理。毫无疑问,作者用形象的描述,简洁诙谐的语言由浅入深的讲述了这一神奇的算法,相信每个读过的人都会对此有所认识(如果没有,那就是偶的翻译太差了--b)。 以下是翻译的正文。(由于本人使用ultraedit编辑,所以没有对原文中的各种链接加以处理(除了图表),也是为了避免未经许可链接的嫌疑,有兴趣的读者可以参考原文。
会者不难,A*(念作A星)算法对初学者来说的确有些难度。 这篇文章并不试图对这个话题作权威的陈述。取而代之的是,它只是描述算法的原理,使你可以在进一步的阅读中理解其他相关的资料。 最后,这篇文章没有程序细节。你尽可以用任意的计算机程序语言实现它。如你所愿,我在文章的末尾包含了一个指向例子程序的链接。 压缩包包括C++和Blitz Basic两个语言的版本,如果你只是想看看它的运行效果,里面还包含了可执行文件。
我们正在提高自己。让我们从头开始...... 序:搜索区域 假设有人想从A点移动到一墙之隔的B点,如下图,绿色的是起点A,红色是终点B,蓝色方块是中间的墙。 [图1] 你首先注意到,搜索区域被我们划分成了方形网格。像这样,简化搜索区域,是寻路的第一步。这一方法把搜索区域简化成了一个二维数组。数组的每一个元素是网格的一个方块,方块被标记为可通过的和不可通过的。路径被描述为从A到B我们经过的方块的集合。一旦路径被找到,我们的人就从一个方格的中心走向另一个,直到到达目的地。 这些中点被称为“节点”。当你阅读其他的寻路资料时,你将经常会看到人们讨论节点。为什么不把他们描述为方格呢?因为有可能你的路径被分割成其他不是方格的结构。他们完全可以是矩形,六角形,或者其他任意形状。节点能够被放置在形状的任意位置-可以在中心,或者沿着边界,或其他什么地方。我们使用这种系统,无论如何,因为它是最简单的。
开始搜索 正如我们处理上图网格的方法,一旦搜索区域被转化为容易处理的节点,下一步就是去引导一次找到最短路径的搜索。在A*寻路算法中,我们通过从点A开始,检查相邻方格的方式,向外扩展直到找到目标。
我们做如下操作开始搜索: 1. 从点A开始,并且把它作为待处理点存入一个“开启列表”。开启列表就像一张购物清单。尽管现在列表里只有一个元素,但以后就会多起来。你的路径可能会通过它包含的方格,也可能不会。基本上,这是一个待检查方格的列表。 2. 寻找起点周围所有可到达或者可通过的方格,跳过有墙,水,或其他无法通过地形的方格。也把他们加入开启列表。为所有这些方格保存点A作为“父方格”。当我们想描述路径的时候,父方格的资料是十分重要的。后面会解释它的具体用途。 3. 从开启列表中删除点A,把它加入到一个“关闭列表”,列表中保存所有不需要再次检查的方格。 在这一点,你应该形成如图的结构。在图中,暗绿色方格是你起始方格的中心。它被用浅蓝色描边,以表示它被加入到关闭列表中了。所有的相邻格现在都在开启列表中,它们被用浅绿色描边。每个方格都有一个灰色指针反指他们的父方格,也就是开始的方格。
[图2] 接着,我们选择开启列表中的临近方格,大致重复前面的过程,如下。但是,哪个方格是我们要选择的呢?是那个F值最低的。
路径评分 选择路径中经过哪个方格的关键是下面这个等式: F = G + H 这里: G = 从起点A,沿着产生的路径,移动到网格上指定方格的移动耗费。 H = 从网格上那个方格移动到终点B的预估移动耗费。这经常被称为启发式的,可能会让你有点迷惑。这样叫的原因是因为它只是个猜测。我们没办法事先知道路径的长度,因为路上可能存在各种障碍(墙,水,等等)。虽然本文只提供了一种计算H的方法,但是你可以在网上找到很多其他的方法。
我们的路径是通过反复遍历开启列表并且选择具有最低F值的方格来生成的。文章将对这个过程做更详细的描述。首先,我们更深入的看看如何计算这个方程。 正如上面所说,G表示沿路径从起点到当前点的移动耗费。在这个例子里,我们令水平或者垂直移动的耗费为10,对角线方向耗费为14。我们取这些值是因为沿对角线的距离是沿水平或垂直移动耗费的的根号2(别怕),或者约1.414倍。为了简化,我们用10和14近似。比例基本正确,同时我们避免了求根运算和小数。这不是只因为我们怕麻烦或者不喜欢数学。使用这样的整数对计算机来说也更快捷。你不就就会发现,如果你不使用这些简化方法,寻路会变得很慢。 既然我们在计算沿特定路径通往某个方格的G值,求值的方法就是取它父节点的G值,然后依照它相对父节点是对角线方向或者直角方向(非对角线),分别增加14和10。例子中这个方法的需求会变得更多,因为我们从起点方格以外获取了不止一个方格。 H值可以用不同的方法估算。我们这里使用的方法被称为曼哈顿方法,它计算从当前格到目的格之间水平和垂直的方格的数量总和,忽略对角线方向。然后把结果乘以10。这被成为曼哈顿方法是因为它看起来像计算城市中从一个地方到另外一个地方的街区数,在那里你不能沿对角线方向穿过街区。很重要的一点,我们忽略了一切障碍物。这是对剩余距离的一个估算,而非实际值,这也是这一方法被称为启发式的原因。想知道更多?你可以在这里找到方程和额外的注解。 F的值是G和H的和。第一步搜索的结果可以在下面的图表中看到。F,G和H的评分被写在每个方格里。正如在紧挨起始格右侧的方格所表示的,F被打印在左上角,G在左下角,H则在右下角。
[图3] 现在我们来看看这些方格。写字母的方格里,G = 10。这是因为它只在水平方向偏离起始格一个格距。紧邻起始格的上方,下方和左边的方格的G值都等于10。对角线方向的G值是14。 H值通过求解到红色目标格的曼哈顿距离得到,其中只在水平和垂直方向移动,并且忽略中间的墙。用这种方法,起点右侧紧邻的方格离红色方格有3格距离,H值就是30。这块方格上方的方格有4格距离(记住,只能在水平和垂直方向移动),H值是40。你大致应该知道如何计算其他方格的H值了~。 每个格子的F值,还是简单的由G和H相加得到
继续搜索 为了继续搜索,我们简单的从开启列表中选择F值最低的方格。然后,对选中的方格做如下处理:
4.把它从开启列表中删除,然后添加到关闭列表中。 5.检查所有相邻格子。跳过那些已经在关闭列表中的或者不可通过的(有墙,水的地形,或者其他 无法通过的地形),把他们添加进开启列表,如果他们还不在里面的话。把选中的方格作为新的方格的父节点。 6.如果某个相邻格已经在开启列表里了,检查现在的这条路径是否更好。换句话说,检查如果我们用新的路径到达它的话,G值是否会更低一些。如果不是,那就什么都不做。 另一方面,如果新的G值更低,那就把相邻方格的父节点改为目前选中的方格(在上面的图表中,把箭头的方向改为指向这个方格)。最后,重新计算F和G的值。如果这看起来不够清晰,你可以看下面的图示。
好了,让我们看看它是怎么运作的。我们最初的9格方格中,在起点被切换到关闭列表中后,还剩8格留在开启列表中。这里面,F值最低的那个是起始格右侧紧邻的格子,它的F值是40。因此我们选择这一格作为下一个要处理的方格。在紧随的图中,它被用蓝色突出显示。
[图4] 首先,我们把它从开启列表中取出,放入关闭列表(这就是他被蓝色突出显示的原因)。然后我们检查相邻的格子。哦,右侧的格子是墙,所以我们略过。左侧的格子是起始格。它在关闭列表里,所以我们也跳过它。 其他4格已经在开启列表里了,于是我们检查G值来判定,如果通过这一格到达那里,路径是否更好。我们来看选中格子下面的方格。它的G值是14。如果我们从当前格移动到那里,G值就会等于20(到达当前格的G值是10,移动到上面的格子将使得G值增加10)。因为G值20大于14,所以这不是更好的路径。如果你看图,就能理解。与其通过先水平移动一格,再垂直移动一格,还不如直接沿对角线方向移动一格来得简单。 当我们对已经存在于开启列表中的4个临近格重复这一过程的时候,我们发现没有一条路径可以通过使用当前格子得到改善,所以我们不做任何改变。既然我们已经检查过了所有邻近格,那么就可以移动到下一格了。 于是我们检索开启列表,现在里面只有7格了,我们仍然选择其中F值最低的。有趣的是,这次,有两个格子的数值都是54。我们如何选择?这并不麻烦。从速度上考虑,选择最后添加进列表的格子会更快捷。这种导致了寻路过程中,在靠近目标的时候,优先使用新找到的格子的偏好。但这无关紧要。(对相同数值的不同对待,导致不同版本的A*算法找到等长的不同路径。) 那我们就选择起始格右下方的格子,如图。 [图5] 这次,当我们检查相邻格的时候,发现右侧是墙,于是略过。上面一格也被略过。我们也略过了墙下面的格子。为什么呢?因为你不能在不穿越墙角的情况下直接到达那个格子。你的确需要先往下走然后到达那一格,按部就班的走过那个拐角。(注解:穿越拐角的规则是可选的。它取决于你的节点是如何放置的。) 这样一来,就剩下了其他5格。当前格下面的另外两个格子目前不在开启列表中,于是我们添加他们,并且把当前格指定为他们的父节点。其余3格,两个已经在关闭列表中(起始格,和当前格上方的格子,在表格中蓝色高亮显示),于是我们略过它们。最后一格,在当前格的左侧,将被检查通过这条路径,G值是否更低。不必担心,我们已经准备好检查开启列表中的下一格了。
我们重复这个过程,知道目标格被添加进开启列表,就如在下面的图中所看到的。