原始链接地址:
http://www.gamedev.net/page/resources/_/technical/artificial-intelligence/a-pathfinding-for-beginners-r2003
Updated July 18, 2005
This article has been translated into Albanian, Chinese, French, German, Portuguese, Russian,
and Spanish.
Other translations are welcome. See email address at the bottom of this article.
这篇文章被翻译成阿尔巴尼亚,中国,法语,德语,葡萄牙语,俄语和西班牙语。其他的翻译是受欢迎的。请看到本文底部的电子邮件地址。
The A* (pronounced A-star) algorithm can be complicated for beginners. While there are many articles on the web that explain A*, most
are written for people who understand the basics already. This article is for the true beginner.
对于初学者来说,A* (发音为 A-star)算法可能很复杂。虽然在网络上有很多解释A*算法的文章,但是大部分的文章只有那些有了A*算法基础的人才能看得懂。这个文章才是真正写给初学者看的。
This article does not try to be the definitive work on the subject. Instead it describes the fundamentals and prepares you to go out
and read all of those other materials and understand what they are talking about. Links to some of the best are provided at the end of this article, under Further Reading.
本文不是力图成为这一主图的权威著作。相反,他描述了一些基础原理,为你走出迷惑,读懂其他材料里面说的是什么做准备。在本文结尾处的Further Reading下面,提供了一些最好的材料。
Finally, this article is not program-specific. You should be able to adapt what‘s here to any computer language. As you might expect,
however, I have included a link to a sample program at the end of this article. The sample package contains two versions: one in C++ and one in Blitz Basic. It also contains executables if you just want to see A* in action.
最后,这个文章不是程序专用的。你应该能够改编这里的东西到任意计算机语言。然而,也许正如你所期望的那样,在这片文章的结尾,我呈上了一个样例程序的链接。这个样例包包含了两个版本,分别是:C++和Blitz Basic。如果你只是想看看A*算法是怎么执行的,这个包里面也包含了供可执行的文件。
But we are getting ahead of ourselves. Let‘s start at the beginning ...
说的有些多,就让我们开始吧...
Introduction: The Search Area
Let‘s assume that we have someone who wants to get from point A to point B. Let‘s assume that a wall separates the two points. This
is illustrated below, with green being the starting point A, and red being the ending point B, and the blue filled squares being the wall in between.
简介:搜索区域
让我们假设一个人想从A点到达B点。假设一堵墙隔开这两点。这就阐明了下面:绿色是起始A点,红色为终止B点,蓝色填充的3个方块是两者间的墙
The
first thing you should notice is that we have divided our search area into a square grid.Simplifying the search area, as we have done here, is the first step in pathfinding. This particular method reduces our search area to a simple two dimensional
array. Each item in the array represents one of the squares on the grid, and its status is recorded as walkable or unwalkable. The path is found by figuring out which squares we should take to get from A to B. Once the path is found, our person moves from
the center of one square to the center of the next until the target is reached.
首先你需要注意的是,我们把搜索区域分割成了一个方形网格。正如我们这里所做的,简化搜索区域是路径搜索的第一步。这个特别的方法让我们的搜索区域简化成了一个二维数组。数组中的每一个元素代表网格中对应的方块。他被标记为可通过和不可通过两种状态。路径的建立是通过计算从A到B我们需要使用的方块。一旦路径建立起来了,我们从一个方块的中心移向另一个方块的中心,直到到达目标。
These center points are called "nodes". When you read about pathfinding elsewhere, you will often see people discussing nodes. Why not
just call them squares? Because it is possible to divide up your pathfinding area into something other than squares. They could be rectangles, hexagons, triangles, or any shape, really. And the nodes could be placed anywhere within the shapes – in the center
or along the edges, or anywhere else. We are using this system, however, because it is the simplest.
这些中心点被称作“节点”。当你在别处读到有关路径寻找时,你会经常发现人们讨论节点。为什么不直接叫他们方块呢?因为有可能你的路径是被划分成其他形状而不是方块。实际上他们可能是长方形、六边形、或者其他形状。并且节点可以放置在形状的任何位置上----中心或者边缘,或者其他任何地方。然而,我们使用这种系统,因为他是最简单的。
Starting
the Search
开始搜索
Once we have simplified our search area into a manageable number of nodes, as we have done with the grid layout above, the next step
is to conduct a search to find the shortest path. We do this by starting at point A, checking the adjacent squares, and generally searching outward until we find our target.
一旦我们把搜索区域简化成了可控数量的节点,正如我们上面已经完成的网格布局。下一步就是进行一次搜索,来找到最短的路径。为此,我们从A点开始,检查相邻的方块,并且逐渐的向外找寻,直到我们找到了我们的终点。
We begin the search by doing the following:
我们通过如下步骤开始寻找:
- Begin at the starting point A and add it to an "open list" of squares to be considered. The open list is kind of like a shopping list. Right now there is just one item on the list, but we will have more later. It contains
squares that might fall along the path you want to take, but maybe not. Basically, this is a list of squares that need to be checked out.从起始A点开始,把它添加到“开放列表”中(这个列表用来存放将要被考虑的方块)。开放列表就像是一张购物单,目前清单上只有一个项目,但是随后将会有更多。他包含了将要走的路径上或者不是路径上的方块。从根本上说这就是一个需要被检查的方块的列表。
- Look at all the reachable or walkable squares adjacent to the starting point, ignoring squares with walls, water, or other illegal terrain. Add them to the open list, too. For each of these squares, save point A as its "parent
square". This parent square stuff is important when we want to trace our path. It will be explained more later.看看起始点周围可以到达或者可以通过的方块,忽略那些墙壁,水,和其他非法地形。也把他们添加到开放列表中。对于这些中的每一个方块,保存起始点A作为他的父方块。当我们要追踪线路时,这个父方块就显得非常重要了。我们会在后面做出解释。
- Drop the starting square A from your open list, and add it to a "closed list" of squares that you don‘t need to look at again for now.
从你的开放列表中删除其实方块A,把它添加到封闭方块列表中,这样你就不用再看他了。
At this point, you should have something like the following illustration. In this illustration, the dark green square in the center
is your starting square. It is outlined in light blue to indicate that the square has been added to the closed list. All of the adjacent squares are now on the open list of squares to be checked, and they are outlined in light green. Each has a gray pointer
that points back to its parent, which is the starting square.
到这里,你应该形成类似下面图解的的思维。在这个图解中,中间的墨绿色方块是你的起始方块,浅蓝色的外部轮廓表明他已经被添加到了封闭列表中。现在开放列表中的所有邻接方块都被查看了,他们被涂上浅绿色的边(图中是深绿色的)。每个方块有一个灰色的指针指回他的父方块,这里是他们的起始方块。
Next,
we choose one of the adjacent squares on the open list and more or less repeat the earlier process, as described below. But which square do we choose? The one with the lowest F cost.
接着,向下面描述的那样,我们选择开放列表中的一个邻接方块。或多或少的重复之前的步骤。但是,我们选择哪一个方块呢?回答是:最小F代价的那个。
Path
Scoring
路径评分
The key to determining which squares to use when figuring out the path is the following equation:
当我们计算路径时,决定使用哪些方块的关键就是下面的公式:
F = G + H
where
其中
- G = the movement cost to move from the starting point A to a given square on the grid, following the path generated to get there.
G = 沿着生成的路径,从起始A点到网格上给定的方块所需的移动代价。
- H = the estimated movement cost to move from that given square on the grid to the final destination, point B. This is often referred to as the heuristic, which can be a bit confusing. The reason why it is called that is because
it is a guess. We really don‘t know the actual distance until we find the path, because all sorts of things can be in the way (walls, water, etc.). You are given one way to calculate H in this tutorial, but there are many others that you can find in other
articles on the web.H = 从网格上给定的方块移动到最终目标B点的估计代价。这通常被指做启发式,可能会有点令人困解。之所以被称作启发式,是因为他是一个猜测。因为在路上有各种各样的东西(墙啊,水啊等等),在我们找到路径之前,我们是不知道实际的距离。在这个教学当中,只给你了一个计算H的方法,但是在网上你可以在其他的文章中找到其他的计算方法。
Our path is generated by repeatedly going through our open list and choosing the square with the lowest F score. This process will be
described in more detail a bit further in the article. First let‘s look more closely at how we calculate the equation.
我们的路径是通过反复的遍历我们的开放列表,选择具有最小F值的方块。这个步骤将会在文章中做进一步的探讨。首先让我们仔细看一下,我们是如何计算这个等式的。
As described above, G is the movement cost to move from the starting point to the given square using the path generated to get there.
In this example, we will assign a cost of 10 to each horizontal or vertical square moved, and a cost of 14 for a diagonal move. We use these numbers because the actual distance to move diagonally is the square root of 2 (don‘t be scared), or roughly 1.414
times the cost of moving horizontally or vertically. We use 10 and 14 for simplicity‘s sake. The ratio is about right, and we avoid having to calculate square roots and we avoid decimals. This isn‘t just because we are dumb and don‘t like math. Using whole
numbers like these is a lot faster for the computer, too. As you will soon find out, pathfinding can be very slow if you don‘t use short cuts like these.
如上所述,G是从起始点到给定方块的移动代价。在这个样例中,我们把单位水平和垂直移动代价赋值为10,对角线移动的代价为14.我们使用这些值是因为世界的对角线移动距离是根号2,不用怕,是1.414倍的水平或垂直移动代价。我们使用10或14只为了简单。比例是近乎正确的,我们避免了计算平方根,同时也避免了小数。这不不仅仅是因为我们不善于数学,或者不喜欢数学之类的。使用整数,可以让计算机更快一些。正如你将会发现的那样,如果你不使用类似的捷径,路径搜索可能很慢。
Since we are calculating the G cost along a specific path to a given square, the way to figure out the G cost of that square is to take
the G cost of its parent, and then add 10 or 14 depending on whether it is diagonal or orthogonal (non-diagonal) from that parent square. The need for this method will become apparent a little further on in this example, as we get more than one square away
from the starting square.
既然我们计算沿着特定路线到给定方块G的代价。计算G代价的方法就是取G的父方块的代价,加上10或者14(这个取决于从父方块到这个方块是沿着对角线还是非对角线)。当我们距离其实方块有超过一个方块时,此例中的这个方法的必要性将会变得稍微明显。
H can be estimated in a variety of ways. The method we use here is called the Manhattan method, where you calculate the total number
of squares moved horizontally and vertically to reach the target square from the current square, ignoring diagonal movement, and ignoring any obstacles that may be in the way. We then multiply the total by 10, our cost for moving one square horizontally or
vertically. This is (probably) called the Manhattan method because it is like calculating the number of city blocks from one place to another, where you can‘t cut across the block diagonally.
可以使用不同的方法来估计H。这里使用的方法叫做Manhattan方法,你可以计算出方块的数量:从当前方块到目标方块垂直和水平移动经过的方块,忽略对角线移动,忽略道路中任何的障碍。然后,我们将总数乘以10,我们的的代价从水平或垂直的方向移动一个方块。这个(也许)称作Manhattan方法是因为他像是计算从一个地方到另一个地方的城市街区数量,你却不能斜着切过街区。
Reading this description, you might guess that the heuristic is merely a rough estimate of the remaining distance between the current
square and the target "as the crow flies." This isn‘t the case. We are actually trying to estimate the remaining distance along the path (which is usually farther). The closer our estimate is to the actual remaining distance, the faster the algorithm will
be. If we overestimate this distance, however, it is not guaranteed to give us the shortest path. In such cases, we have what is called an "inadmissible heuristic."
读完这个描述,你也许会猜测启发式仅仅就是对当前方块到目标方块间直线距离的一个粗略的估计。并非如此,我们实际上尝试估计沿着路径上的剩余距离(通常更远)。我们的估计越接近实际剩余距离,算法执行的越快。然而,如果我们过高的估计这个距离,就不能保证得到的是最短的路径。在这种情况下,我们有称之为“不可采纳启发。”
Technically, in this example, the Manhattan method is inadmissible because it slightly overestimates the remaining distance. But we
will use it anyway because it is a lot easier to understand for our purposes, and because it is only a slight overestimation. On the rare occasion when the resulting path is not the shortest possible, it will be nearly as short. Want to know more? You can
find equations and additional notes on heuristics here.
从技术上来讲,在这个样例中,Manhattan方法是不可采纳的,因为他有点稍微高估剩余距离。但是我们无论如何将使用Manhattan,因为对我们而言,他是很容易理解的,因为他仅仅是稍微的高估。在罕见的场合下,产生的路径可能不是最短的。但是他也是近乎最短的。想了解更多?您可以在这里发现启发式的等式和附加说明。
F is calculated by adding G and H. The results of the first step in our search can be seen in the illustration below. The F, G, and
H scores are written in each square. As is indicated in the square to the immediate right of the starting square, F is printed in the top left, G is printed in the bottom left, and H is printed in the bottom right.
F是通过相加G和H得到的。在我们的搜索中,第一步的结果可以在下面的说明中看到。F,G,H的值都写在每一个方块中。正如显示的那样,起始方块相邻右边的方块中,F印在左上角,G印在左下角,H印在右下角。
So
let‘s look at some of these squares. In the square with the letters in it, G = 10. This is because it is just one square from the starting square in a horizontal direction. The squares immediately above, below, and to the left of the starting square all have
the same G score of 10. The diagonal squares have G scores of 14.
那么,让我们来看看某些方块,有字母的那个方块,G =10.这是因为,他是一个起始方块水平方向上的方块。紧接起始方块的上面,下面,左边的方块都拥有相同的G值,G=10。对角线上的方块的G值为14.。
The H scores are calculated by estimating the Manhattan distance to the red target square, moving only horizontally and vertically and ignoring the wall that is in the way. Using this method, the square to the immediate right of the start is 3 squares from
the red square, for a H score of 30. The square just above this square is 4 squares away (remember, only move horizontally and vertically) for an H score of 40. You can probably see how the H scores are calculated for the other squares.
H值的计算,是通过估计到红色目标方块的Manhattan距离。仅仅是水平和垂直移动,并且忽略路途中的墙。使用这个方法,起始方块到目标红色方块间的距离是3个方块。H的值就是30.这个方块上面的方块到达红色方块的距离为40(记得只能在水平,垂直方向移动)。你也许可以看出其他的方块的H值是怎么计算出来的。
The F score for each square, again, is simply calculated by adding G and H together.
再次声明,每个方块的F的值,仅仅是通过相加G和H得到的。
Continuing
the Search
继续搜索。。。
To continue the search, we simply choose the lowest F score square from all those that are on the open list. We then do the following
with the selected square:
为了继续搜索,我们仅仅选择在开放列表中最小F值的那个方块。然后我们对选择的方块做如下操作:
- Drop it from the open list and add it to the closed list.
从开放列表中删除它,然后把它放到封闭列表中。
- Check all of the adjacent squares. Ignoring those that are on the closed list or unwalkable (terrain with walls, water, or other illegal terrain), add squares to the open list if they are not on the open list already. Make
the selected square the "parent" of the new squares.检查所有的相邻方块。忽略封闭列表中的方块,以及不可通过的方块(地形上面有墙,有水,或者其他非法地形),如果不在开放列表中,请把他们添加到开发列表中。让选中的方块作为新选择的方块的"父”方块。
- If an adjacent square is already on the open list, check to see if this path to that square is a better one. In other words, check to see if the G score for that square is lower if we use the current square to get there.
If not, don‘t do anything.On the other hand, if the G cost of the new path is lower, change the parent of the adjacent square to the selected square (in the diagram above, change the direction of the pointer to point at the selected square). Finally, recalculate both the F and G scores
of that square. If this seems confusing, you will see it illustrated below.如果相邻方块已经在开放列表中,查看到那个方块的路径是不是更好的一个。也就是说,看看如果我们使用这个方块到达那里,那个方块的G是不是较低的。如果不是,就什么也不做。
另一方面,如果新路径的G的值是较小的,修改相邻的方块的父方块为选中的方块(上图中,修改指针的方向,指向选中的方块)。最后,重新计算这个方块的F和G的值,如果这个看起来有点困惑,请看下面的图示。
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
是图示,不是这个
拿起始点,F方块和F方块上面的那个方块来说,为了方便起见,F上面的那个方块称之为F1方块。首先起始方块周围的8个方块被放在了开放列表中,水平和垂直方向上的G=10,对角线上的G=14;右上角和右下角的方块的H值是40,右边的方块的H值是30,此时选择右侧的那个方块拥有最小的F值,F=40。然后从开放列表中删除F方块,把它放到封闭列表中,然后选择所有合法的相邻方块。共有4个,起始方块的上面下面两个,以及F方块的上面下面两个,因为起始方块和F方块此时已经在封闭列表中了。把F方块作为新选中的4个方块的父方块。但是在之前,已经将F方块上面的方块和下面的方块放在了开放列表中,就需要比较起始点到F1方块和起始点经过F方块到F1方块两条路径上G值的大小,分别是14和20)
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Okay, so let‘s see how this works. Of our initial 9 squares, we have 8 left on the open list after the starting square was switched
to the closed list. Of these, the one with the lowest F cost is the one to the immediate right of the starting square, with an F score of 40. So we select this square as our next square. It is highlight in blue in the following illustration.
那好,就让我们看看这个是如何工作的。在我们出示的9个方块中,我们继起始方块被放在封闭列表后,我们有8个在开放列表中。这些当中,拥有最小F值的那个,就是起始方块紧邻右侧的那个,F值是40。因此,我们选择这个方块作为我们的下一个方块。我们在下面的图示中用蓝色高光标记。
First,
we drop it from our open list and add it to our closed list (that‘s why it‘s now highlighted in blue). Then we check the adjacent squares. Well, the ones to the immediate right of this square are wall squares, so we ignore those. The one to the immediate left
is the starting square. That‘s on the closed list, so we ignore that, too.
首先,我们从开放列表中把它删除,并添加到封闭列表中(这就是为什么他现在是蓝色高光显示的)。然后我们检查相邻的方块。额……紧邻右侧的方块是一堵墙,因此,我们忽略这些。他的左侧是一个起始方块,在封闭列表中,因此,我们也忽略它。
The other four squares are already on the open list, so we need to check if the paths to those squares are any better using this square
to get there, using G scores as our point of reference. Let‘s look at the square rightabove
our selected square. Its current G score is 14. If we instead went through the current square to get there, the G score would be equal to 20 (10, which is the G score to get to the current square, plus 10 more to go vertically to the one just above
it). A G score of 20 is higher than 14, so this is not a better path. That should make sense if you look at the diagram. It‘s more direct to get to that square from the starting square by simply moving one square diagonally to get there, rather than moving
horizontally one square, and then vertically one square.
另外的4个方块,已经在开放列表中了。因此我们需要检查,是否通向这些方块的路径
比 使用选定的方块到达这些方块 的路径 要更好(就是比G的大小)。使用G的值作为我们的参照点,让我们看看我们选中方块的正上面的那个,他的G的值是14。如果我们使用当先的方块到达上面的方块,G的值是20(10,是到达当前方块的G的值,再加上一个10,用作垂直移动一个方块的距离)。G值20,比14高,因此,这不是一个较好的路径。如果你看一下图,你会有更好的理解。更直接的到达那个方块的路径,则是 仅仅通从方块的对角线移动到那里,而不是先是水平移动一个方块,然后垂直移动一个方块。
When we repeat this process for all 4 of the adjacent squares already on the open list, we find that none of the paths are improved
by going through the current square, so we don‘t change anything. So now that we looked at all of the adjacent squares, we are done with this square, and ready to move to the next square.
当我们为开放列表中的所有4个相邻方块重复这个步骤时,我们发现通过当前的方块没有路径得到改进。因此我们不改变任何东西。既然我们看所有相邻的方块,我们已经做完这个方块,已经准备移到另一个方块。
So we go through the list of squares on our open list, which is now down to 7 squares, and we pick the one with the lowest F cost. Interestingly,
in this case, there are two squares with a score of 54. So which do we choose? It doesn‘t really matter. For the purposes of speed, it can be faster to choose the last one
you added to the open list. This biases the search in favor of squares that get found later on in the search, when you have gotten closer to the target. But it doesn‘t really matter. (Differing treatment of ties is why two versions of A* may find different
paths of equal length.)
我们遍历开放列表中的所有方块,现在降到了7个方块,我们选择其中一个拥有最小F值的那个。有趣的是,在这个例子中,有两个方块的值是54。那么我们选择哪一个呢?实际上并不重要。对于速度而言,选择加入到开放列表中的最后一个会更快。当你已经接近于目标时,这将使得搜索更有利于后来搜到的方块。
到发现后来在搜索,当你得到更接近目标有利于正方形的搜索。但它其实并不重要。
(区别于不同的处理方法,所以两个版本的A *可能找到等长的不同路径。)
So let‘s choose the one just below, and to the right of the starting square, as is shown in the following illustration.
所以,让我们选择下面的 和 起始方块右边的方块。正如下图显示的那样。
This
time, when we check the adjacent squares we find that the one to the immediate right is a wall square, so we ignore that. The same goes for the one just above that. We also ignore the square just below the wall. Why? Because you can‘t get to that square directly
from the current square without cutting across the corner of the nearby wall. You really need to go down first and then move over to that square, moving around the corner in the process. (Note: This rule on cutting corners is optional. Its use depends on how
your nodes are placed.)
这一次,当我们查看相邻的方块时,我们发现紧邻右侧是一个墙方块,因此我们忽略他。右侧上面也是墙方块,我们也忽略他。我们也忽略墙下面的方块。为什么?因为如果你不切着过墙角,你是无法直接从当前方块到达墙下面的那个方块的。在这个过程中,你真的需要先向下走然后朝着那个方块移动,绕着拐角移动。(注意:这个规则在切开的拐角是可选的。他的使用基于你的节点是怎么摆放的。)
That leaves five other squares. The other two squares below the current square aren‘t already on the open list, so we add them and the
current square becomes their parent. Of the other three squares, two are already on the closed list (the starting square, and the one just above the current square, both highlighted in blue in the diagram), so we ignore them. And the last square, to the immediate
left of the current square, is checked to see if the G score is any lower if you go through the current square to get there. No dice. So we‘re done and ready to check the next square on our open list.
还剩下5个方块(一个方块周围8个方块,去掉两个墙方块,一个墙下面的方块,还剩5个)。其他的处在下方的方块不在开放列表中(F为88和74的那两个),因此我们把当前的方块作为他们两个的父方块。其他的3个方块,两个已经在封闭列表中(起始方块,当前方块的上面的那一个方块,在图中都用蓝色高光标记着)我们忽略他们。最后一个方块,也就是当前方块的左边一个,需要查看 如果你从当前的方块到达他 G值是不是小一些。不成功。因此我们照做,然后检查开放列表中的另一个方块。
We repeat this process until we add the target square to the closed list, at which point it looks something like the illustration below.
我们重复这个步骤,知道我们把目标方块添加到封闭列表中,此时看起来有点像下面的图。
Note
that the parent square for the square two squares below the starting square has changed from the previous illustration. Before it had a G score of 28 and pointed back to the square above it and to the right. Now it has a score of 20 and points to the square
just above it. This happened somewhere along the way on our search, where the G score was checked and it turned out to be lower using a new path – so the parent was switched and the G and F scores were recalculated. While this change doesn‘t seem too important
in this example, there are plenty of possible situations where this constant checking will make all the difference in determining the best path to your target.
注意,和前面的一幅图相比,F值为80的那个方块,现在变了。之前他的G值为28,指向他右上方的那个方块。现在他的G值为20.在我们搜索的某时刻发生的,适当查看G的值时,使用新的路径他的值更低 ---- 因此他的父方块被改变了,G和F的值被重新计算了。在这个例子中,这个改变似乎不那么重要。有很多可能的情况下,这种持续的检查会使得在确定到你的目标的最佳路径有较大的差别。
So how do we determine the path? Simple, just start at the red target square, and work backwards moving from one square to its parent,
following the arrows. This will eventually take you back to the starting square, and that‘s your path. It should look like the following illustration. Moving from the starting square A to the destination square B is simply a matter of moving from the center
of each square (the node) to the center of the next square on the path, until you reach the target.
那么,怎么决定路径呢?很简单,从红色的目标方块开始,从一个方块到他的父方块
这样 沿着箭头倒着移动。这最终将把你带到其实方块,那就是你的路径。他看起来像下面的图示。从起始方块A点开始移动到目标B点,仅仅就是按照线路从一个方块(节点)的中心,移动到另一个方块的中心,直到到达目标。
Summary
of the A* Method
A*
算法的总结
Okay, now that you have gone through the explanation, let‘s lay out the step-by-step method all in one place:
好了,现则你也许读完了所有的讲解,让我们在这里做一步步的陈述:
- Add the starting square (or node) to the open list.
把起始方块(或者 节点)添加到开放列表中。
- Repeat the following:
重复一下步骤:
a) Look for the lowest F cost square on the open list. We refer to this as the current square.
在开放列表中,寻找最低F值的方块。我们把它作为当前的方块。
b) Switch it to the closed list.
把它放到封闭列表中。
c) For each of the 8 squares adjacent to this current square …
对于邻接这个方块的8个方块中,每一个方块做如下操作:
- If it is not walkable or if it is on the closed list, ignore it. Otherwise do the following.
如果不可通过 或者 已经在封闭列表中, 忽略他们。否则,执行以下操作。
- If it isn‘t on the open list, add it to the open list. Make the current square the parent of this square. Record the F, G, and H costs of the square.
如果不是开放列表中,将它添加到开放列表。让当前的方块作为这个方块的父方块。记录方块的F,G和H的值。
- If it is on the open list already, check to see if this path to that square is better, using G cost as the measure. A lower G cost means that this is a better path. If so, change the parent of the square to the current square,
and recalculate the G and F scores of the square. If you are keeping your open list sorted by F score, you may need to resort the list to account for the change.如果已经在开放列表中了,查看这条路径是不是通向那个方块的较好的路径,使用G作为测量标准。较低的G值意味着,这是一个更好的路径。如果这样,修改当前方块的父方块,重新计算这个方块的G和F值。如果你的开放列表是按照F值排序的,为此,你也许需要重新排序这个列表。
d) Stop when you:
停止时间:
- Add the target square to the closed list, in which case the path has been found (see note below), or
把目标方块添加到目标方块,这种情况,已经查找到路径(见下文附注),或者
- Fail to find the target square, and the open list is empty. In this case, there is no path.
没有找到目标方块,并且开放列表已空。这种情况,没有路径
- If it is not walkable or if it is on the closed list, ignore it. Otherwise do the following.
- Save the path. Working backwards from the target square, go from each square to its parent square until you reach the starting square. That is your path.
保存路径。从目标方块往回走,从每个正方形到它的父方形,直到你到达开始方块。这就是你的路径。
Note:
In earlier versions of this article, it was suggested that you can stop when the target square (or node) has been added to the open list, rather than the closed list. Doing this will be faster and it will almost always
give you the shortest path, but not always. Situations where doing this could make a difference are when the movement cost to move from the second to the last node to the last (target) node can vary significantly -- as in the case of a river crossing between
two nodes, for example.
注:在早期版本的这篇文章中,有人建议,当目标方形(或节点)已经加入到开放列表,而不是封闭的列表,你可以停下来。这样做会更快,它几乎总是给你的最短路径,但并非总是如此。情况是:当运行成本从第二移动到最后一个节点到最后一个(目标)节点可以显著的改变-
例如,渡河的情况下的在两个节点之间。
A* Pathfinding for Beginners A*算法路径搜索入门,布布扣,bubuko.com