我們假設要從綠色區域A移動到紅色區域B,深藍色代表不可行走的區域。
第一步:首先將尋路區域划分成小格子;
第二步:從起點A開始,將其加入到一個由方格組成的openList(開放列表)中。這個openList剛開始只有一個數據,就是起點A。openList里的路徑可能是沿途經過的,也有可能不經過。
openList是一個待檢查的方格列表。
第三步:查看與起點A相鄰的方格(忽略其中不可行走的方格),把其中可行走或可到達的方格加入到openList中。把起點A設置為這些相鄰方格的父親。當我們在追蹤路徑時,這些父節點很重要。
第四步:把A節點從openList中移除,加入到closeList(封閉列表)中,closeList的每個方格都是現在不需要再關注的。
第五步:我們需要從openList中選一個與A節點相鄰的方格。重復下面的步驟,找出具有最小F值的那個節點:
F = G + H。G表示從起點A移動到當前節點的移動代價;H表示從指定的節點移動到終點B的估算成本。
如上所述:
G是從起點A移動到指定節點的移動代價。在本例中,橫向和縱向的移動代價為10,對角線的移動代價為14.之所以使用這些數據,是因為實際的對角移動距離是2的平方根。我們避免了開方
和小數的計算。這並不是代表沒有這個能力或不喜歡數學。而是可以使計算變的更快。
這里有很多種方法估算H值。這里我們使用Manhattan方法,計算從當前節點橫向或縱向移動到達目標所經過的方格數,忽略對角運動,然后把總數乘以10.由於是忽略路徑中的障礙物,所以是對剩
余距離的估算值,而不是實際值,因此稱為試探法。
每個方格的左下角表示G;右下角表示H;左上角表示F
第六步:我們從openList中選擇F值最小的節點,然后對其做以下操作:
1. 把該節點從openList中取出,放到closeList里;
2. 檢查所有與它相鄰的方格,忽略其中在closeList中或不可行走的方格;如果可行走的方格不在openList中,則把它們加入到openList中。把當前選定的節點設置為這些新加入的方格的父親。
第七步:如果某個相鄰的方格已經在openList中,則檢查這條路是否更優。也就是經由當前節點(我們選中的方格)到達那個方格是否具有更小的G值,如果沒有則不做任何操作。否則,如果G值更小
則把那個方格的父親設置為當前方格(重新遍歷那個方格的父親)。然后重新計算那個方格的F值和G值。並且走第八步。
第八步:因為再次遍歷我們的openList,而左邊的那個節點已經在closeList里了,所以只有7個節點了。我們需要選擇F值最小的那個。當方格中有相同的F值時,從速度上考慮,選擇最后加入openList的方格更快。
我們選擇起點A右下方的方格。
第九步:不斷重復上個過程,直到把終點也加入到openList中,此時如下圖所示:
那么我們怎么樣去確定實際路徑呢?很簡單,從終點開始,按着箭頭向父節點移動,這樣就被帶回了起點,也就是路徑。