A 尋路初探

2021-08-17 05:06:05 字數 2161 閱讀 9926

a*尋路初探

原文:patrick lester

翻譯:panic

2023年3月18日

原文出處:a* pathfinding for beginners

譯者序很久以前就知道了a*演算法,但是從未認真讀過相關的文章,也沒有看過**,只是腦子裡有個模糊的概念。這次決定從頭開始,研究一下這個被人推崇備至的簡單方法,作為學習人工智慧的開始。

這篇文章非常知名,國內應該有不少人翻譯過它,我沒有查詢,覺得翻譯本身也是對自身英文水平的鍛鍊。經過努力,終於完成了文件,也明白的a*演算法的原理。毫無疑問,作者用形象的描述,簡潔詼諧的語言由淺入深的講述了這一神奇的演算法,相信每個讀過的人都會對此有所認識(如果沒有,那就是偶的翻譯太差了--b)。

以下是翻譯的正文。(由於本人使用ultraedit編輯,所以沒有對原文中的各種鏈結加以處理(除了圖表),也是為了避免未經許可鏈結的嫌疑,有興趣的讀者可以參考原文。

會者不難,a*(唸作a星)演算法對初學者來說的確有些難度。

這篇文章並不試圖對這個話題作權威的陳述。取而代之的是,它只是描述演算法的原理,使你可以在進一步的閱讀中理解其他相關的資料。

最後,這篇文章沒有程式細節。你盡可以用任意的計算機程式語言實現它。如你所願,我在文章的末尾包含了乙個指向例子程式的鏈結。 壓縮包包括c++和blitz basic兩個語言的版本,如果你只是想看看它的執行效果,裡面還包含了可執行檔案。

我們正在提高自己。讓我們從頭開始......

序:搜尋區域

假設有人想從a點移動到一牆之隔的b點,如下圖,綠色的是起點a,紅色是終點b,藍色方塊是中間的牆。

[圖1]

你首先注意到,搜尋區域被我們劃分成了方形網格。像這樣,簡化搜尋區域,是尋路的第一步。這一方法把搜尋區域簡化成了乙個二維陣列。陣列的每乙個元素是網格的乙個方塊,方塊被標記為可通過的和不可通過的。路徑被描述為從a到b我們經過的方塊的集合。一旦路徑被找到,我們的人就從乙個方格的中心走向另乙個,直到到達目的地。

這些中點被稱為「節點」。當你閱讀其他的尋路資料時,你將經常會看到人們討論節點。為什麼不把他們描述為方格呢?因為有可能你的路徑被分割成其他不是方格的結構。他們完全可以是矩形,六角形,或者其他任意形狀。節點能夠被放置在形狀的任意位置-可以在中心,或者沿著邊界,或其他什麼地方。我們使用這種系統,無論如何,因為它是最簡單的。

開始搜尋

正如我們處理上圖網格的方法,一旦搜尋區域被轉化為容易處理的節點,下一步就是去引導一次找到最短路徑的搜尋。在a*尋路演算法中,我們通過從點a開始,檢查相鄰方格的方式,向外擴充套件直到找到目標。

我們做如下操作開始搜尋:

從點a開始,並且把它作為待處理點存入乙個「開啟列表」。開啟列表就像一張購物清單。儘管現在列表裡只有乙個元素,但以後就會多起來。你的路徑可能會通過它包含的方格,也可能不會。基本上,這是乙個待檢查方格的列表。

尋找起點周圍所有可到達或者可通過的方格,跳過有牆,水,或其他無法通過地形的方格。也把他們加入開啟列表。為所有這些方格儲存點a作為「父方格」。當我們想描述路徑的時候,父方格的資料是十分重要的。後面會解釋它的具體用途。

從開啟列表中刪除點a,把它加入到乙個「關閉列表」,列表中儲存所有不需要再次檢查的方格。

在這一點,你應該形成如圖的結構。在圖中,暗綠色方格是你起始方格的中心。它被用淺藍色描邊,以表示它被加入到關閉列表中了。所有的相鄰格現在都在開啟列表中,它們被用淺綠色描邊。每個方格都有乙個灰色指標反指他們的父方格,也就是開始的方格。

[圖2]

接著,我們選擇開啟列表中的臨近方格,大致重複前面的過程,如下。但是,哪個方格是我們要選擇的呢?是那個f值最低的。

路徑評分

選擇路徑中經過哪個方格的關鍵是下面這個等式:

f = g + h
這裡:

好,現在你已經看完了整個說明,讓我們把每一步的操作寫在一起:

把起始格新增到開啟列表。

重複如下的工作:

a) 尋找開啟列表中f值最低的格仔。我們稱它為當前格。

b) 把它切換到關閉列表。

c) 對相鄰的8格中的每乙個?

d) 停止,當你

儲存路徑。從目標格開始,沿著每一格的父節點移動直到回到起始格。這就是你的路徑。

迷宮尋路(A星尋路演算法)

題目 假設我們有乙個7 5大小的迷宮,如下圖所示,綠色格仔表示起點,紅色的格仔表示終點,中間的3個深灰色格仔表示障礙物。請找到一條從起點到終點最短的路徑。解題思路 需要引入兩個集合和乙個公式,如下 具體步驟 把起點放入openlist 檢查openlist中是否有值,如果沒有則無法到達終點,結束尋路...

python尋路 A 尋路演算法 python實現

coding utf 8 import math import cv2 as cv class point object def init self,position,parent self.position position self.parent parent self.f 0 self.g 0...

A 尋路演算法

問題 由於遊戲中尋路出了個小問題 玩家尋路到乙個死角後在那邊不停的來回跑,就是無法越過障礙物,就研究了下a 尋路演算法以解決這個問題 研究了幾天,自己寫了個demo這裡給出總結 原理 a 演算法給出的是權值最優的路徑而不是最短路徑 權值有f g h來表示 啟發式函式如下 f p g p h p h值...