A*算法詳解


預備知識

A*算法的基本原理

\(A*\)

A-star是什么?下面是百度的解釋 >A-star算法是一種靜態路網中求解最短路徑最有效的直接搜索方法,也是解決許多搜索問題的有效算法。算法中的距離估算值與實際值越接近,最終搜索速度越快。
 F[i]=G[i]+H[i];

以上式子中\(G[i]\)表示從起點到當前節點已經付出的代價,這個是准確的
\(A*\)算法最重要的是估價函數\(H[i]\)的設計,\(H[i]\)是估價函數,表示當前節點到終點的預計代價,當估價函數設為\(0\)時,就和普通的最短路沒有區別,設從當前節點到終點的真實值為\(X[i]\)\(H[i]\)越接近\(X[i]\),那么這個算法效率就越高,但需要注意一點。
我們要保證\(H[i]<=X[i]\),一旦大於,那么\(A*\)算法不能保證其正確性。

想必大家都很熟悉\(BFS\)了,在我的淺顯的理解中,\(A*\)是對\(BFS\)的優化。

\(A*\)尋路

\(Q:\)假設有人想從\(A\)點移動到一牆之隔的\(B\)點,如下圖,綠色的是起點\(A\),紅色是終點\(B\),藍色方塊是中間的牆,假設走一格的代價為10,周圍有八個方向可以移動,對角線的代價是\(10\sqrt 2\),要求輸出最優的路徑。


第一個想法是用\(BFS\)(但我們是在講\(A*\)啊喂)
然后我們還是要用\(A*\)的方法解決,和\(BFS\)很像,我們先開一個優先隊列(按照F值從小到大排序),然后將起點周圍的八個節點放入隊列中,利用上面的公式\(F[i]=G[i]+H[i]\),這里不要求輸出最優解,所以對角線用\(14\)近似即可,在格點圖中,\(H[i]\)通常使用當前節點與終點的曼哈頓距離,這樣\(H[i]\)也可以用\(O(1)\)的復雜度求出。
現在我們再開兩個數組\(vis[i]、T[i]\)\(vis\)標記了還在隊列中的節點,\(T[i]\)表示不用再被訪問的節點
然后我們用一個數組存儲當前節點從哪個節點轉移而來,方便輸出路徑。當第一波操作完成后的情況是這樣的。(左上角表示F值,左下角G值,右下角H值)

下面我們開始一系列操作
\(1.\)找出當前隊列中的隊首(其實就是\(F\)值最小的那個),將它取消標記在隊列\(vis\)中,放入\(T\)中(一定要區分這兩個數組,因為每次取的是最優解,這個節點一定不會被更優地更新了,所以它就像障礙物不用再訪問了),然后將它擴展,重新計算出\(G、H、F\),設置父節點,並且將這個節點標記已經訪問(\(vis\)),放入隊列。
\(2.\)如果遇到障礙物或在\(T\)中的節點,則跳過
\(3.\)如果遇到在\(vis\)的節點,檢查轉移后\(G\)值是否小於上次搜索到時的\(G\)值,如果是,那么更新這個節點的所有信息,重新計算,然后很重要的一點是重新設置父節點
好的,接下來不停進行這種操作,直到找到最終節點。

最后要做的,就是從終點開始訪問父節點,將路徑逆推出來就大功告成了,\(A*\)算法到此為止。

\(Code\)

什么你要\(Code?\)不好意思暫時沒有


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM