A*尋路初探

 轉自:http://dev.gameres.com/Program/Abstract/Arithmetic/A%20Pathfinding%20for%20Beginners.htm

路徑排序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 kinds of stuff 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. We then multiply the total by 10. This is called the Manhattan method because it's like calculating the number of city blocks from one place to another, where you can't cut across the block diagonally. Importantly, when calculating H, we ignore any intervening obstacles. This is an estimate of the remaining distance, not the actual distance, which is why it's called the heuristic. Want to know more? You can find equations and additional notes on heuristics here.
H能通過多種方法估算。我們這裏用到的方法叫做Manhattan方法,計算從當前方塊經過水平/垂直移動而到達目標方塊的方塊總數。然後將總數乘以 10。這種方法之所以叫做Manhattan方法,因爲他很象計算從一個地點到達另一個地點的城市街區數量計算,此時你不能斜向的穿越街區。重要的是,當計算H的時候,要忽略任何路徑中的障礙。這是一個對剩餘距離的 估算值,而不是實際值,這就是試探法的稱謂由來。想知道更多?關於試探法的更多說明在這裏

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.
G和H相加就算出了F。第一步搜索的結果見下圖的描述。F,G,和H值都寫入了每個方塊。如開始方塊相鄰右邊的方塊,F顯示在左上方,G顯示在左下方,而 H顯示在右下方。


[圖 3][Figure 3]

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值: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。其上的方塊距離爲4(記住,只能水平或者垂直移動),H就是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值的方塊。然後對選定的方塊做如下操作:

  1. Drop it from the open list and add it to the closed list.
  2. 將他從開放列表取出,並加入封閉列表。
  3. 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.
  4. 測試所有的相鄰方塊。忽略封閉列表內的和不可行走的(牆,水及其它非法地形)方塊,如果方塊不在開放列表中,則添加進去。將選定方塊作爲這些新加入方塊的父親。
  5. 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.
  6. 如果一個相鄰方塊已經存在於開放列表,檢查到達那個方塊的路徑是否更優。換句話說,檢查經由當前方塊到達那裏是否具有更小的G 值。如果沒有,不做任何事。
    相反,如果新路徑的G值更小,把這個相鄰方塊的父親改爲當前選定的方塊(在上圖中,修改其指針方向指向選定方塊)。最後,重新計算那個方塊的F和G值。如果這樣還是很迷惑的話,後面還會有圖解說明。

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。所以我們選定這個塊作爲下一個方塊。在隨後的圖例中,它以高亮的藍色表示。


[圖 4][Figure 4]

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 right above 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值是14。如果我們經由當前方塊到達那裏,G值將是20(10,到達當前方塊的G值,再加上10垂直移動到它上面的方塊)。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.
我們選擇下面的那個,位於開始方塊的右邊,如下圖所示。


[圖 5][Figure 5]

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個方塊了。當前方塊下的兩個方塊不在開放列表中,所以要添加他們,並把當前方塊作爲它們的父親。在另外三個方塊中,有兩個已經在封閉列表中了(開始方塊,和當前方塊上面的那個,它們都用高亮的藍色在圖中標出來了),所以忽略它們。最後一個方塊,當前方塊相鄰左邊的那個,檢查經由當前方塊到達那裏是否得到更小的G值。沒有。所以處理完畢,並準備檢查開放列表中的下一個方塊。

We repeat this process until we add the target square to the open list, at which point it looks something like the illustration below.
我們重複這個過程,直到把目標點添加到開放列表,此時的情形如下圖所示。


[圖 6][Figure 6]

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.
注意開始方塊向下的第二個方塊,在前面的描述中其父親已經發生改變。開始它的G值爲28,指向其右上角的方塊。現在它的值是20,指向其上方的方塊。這是在搜索方法中某處發生的嗎?在那裏G值被檢查,而且使用新的路徑後,它得到了更小的值。所以它的父親切換了,G和F也重新計算。而這個改變在本例中不見得非常重要,還有足夠多的可能位置,在決定最佳路徑的時候,持續的檢查會產生各種差別。

So how do we determine the actual path itself? 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. Simple!
那麼我們怎樣決定實際的路徑呢?簡單,從紅色目標方塊開始,向後移動到它的父親,跟從箭頭的指示。最終你會回到開始方塊,這就是路徑!它應該如下圖所示。從方塊A移動到目標方塊B就是從每一個方塊(節點)的中心移動到路徑上的下一個方塊的中心的簡單過程,直到到達目標。簡單!


[圖 7][Figure 7]


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章