A 演算法 整理

2022-09-24 05:24:14 字數 2847 閱讀 8909

a*演算法

目錄2.總結

注:本文引自

概念

​ a*探路搜尋,是指在有障礙物的時候,尋找到達目的地最短路徑的搜尋。

先介紹一些前置知識助於自己理解a*:

啟發式搜尋:這是對每乙個搜尋位置進行評估,得到好的位置,再從這個位置進行搜尋直到目標。

這樣子好處是:剪枝,效率更高。

啟發式搜尋的關鍵是如何進行估價。

估價函式:從當前節點到目的的預估費用。此估計就是啟發式的。在尋路問題與迷宮問題中,通常用manhattan估價函式預估費用。

a*與一般搜尋的關係區別:dfs bfs是a*演算法的特例。

對於bfs演算法,是從當前節點擴充套件出的每個節點(未被訪問)放進佇列,從而進一步拓展。其估價函式h為0,邊權為1,無任何啟發式資訊。dfs的h為0。

選取最小估價:選擇最小估價的節點,用到最小優先順序佇列(最小二叉堆),c++ stl中有現有的資料結構priority_queue,需要過載自定義節點操作比較符。

a*演算法評價:理論上時間最優,但空間增長為指數級別。

ida*演算法:迭代加深a*演算法,解決空間指數增長問題,甚至可以不用優先順序佇列。

綠色為起點,紅色為重點,藍色為障礙物。

我們應注意到,整個區域被劃分為正方形網格,而我們的搜尋區域是正方形擴散。

那麼這是演算法第一步:

我們將每乙個正方形區域用二維陣列來儲存,二位陣列的每個元素代表其位置,二維陣列的值可以表示為可以通過以及不可通過。

那麼路徑的求解就是從綠色方塊a到紅色方塊b的二維陣列方塊的集合。

我們把路徑經過的區域叫節點,不叫方塊。因為路徑完全可以分割成不是正方形的形狀,如六邊形,矩形。只不過正方形是最簡單的情況。

從a 開始,檢查相鄰的方格,向外拓展。

具體操作:

從a開始,將其放入open_list中,open_list 像乙個購物清單。其中的內容可能是最終的路徑也可能不是。基本上這是待檢查方格的清單。

尋找周圍可到達方格,也將其加入open_list中,並儲存為點a的父方格。父方格的作用很重要,後續會講到。

開啟列表刪除點a ,加入close_list,這是儲存不需要檢查的方格

藍框描邊的是在close_list中,旁邊擴散的箭頭是其父節點。

接下來就是要開始啟發式搜尋用哪個節點了,這裡的關鍵是路徑評分。

具體評分的函式寫法f=g+h

*g:從起點開始,移動到現節點的移動耗費。比如這裡每移動,橫豎向10,對角向14(不用根號是為了簡化)

*h:現節點移動到終點的預估耗費。這裡就被稱為啟發式,因為他只是乙個猜測。預估的辦法這裡提供一種manhattan估價函式預估費用。即計算從此節點到終點,只走橫向豎向的數量總和,再乘以10.(忽略障礙物),請注意這裡是估算,非實際值。所以他叫啟發式。

那麼最後的評分就是兩者和。

這是評分結果。

我們從open_list中選擇f最低的方格,對其做如下處理:

1.從open_list移除,加入close_list中去。

2.檢查所有相鄰格仔。跳過open_list中的格仔以及不可達的格仔(牆,地形),將未被跳過的加入到open_list中,然後他們作為此節點的父節點。

3.如果相鄰節點中已有在open_list中的,檢查通過新路徑快,還是從那個已在open_list中的節點的父節點過來快。

如圖,既然我們都在open_list中,那我們檢查g值,發現新路徑是右+下,g的值為20,原路徑是只要對角線,g的值為14,所以明顯舊路徑好。

重複這個過程直至到達終點。

最後確定路線是從終點沿著父節點倒過來就是路徑了。

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

2,重複如下的工作:

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

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

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

​ * 如果它不可通過或者已經在關閉列表中,略過它。反之如下。

​ * 如果它不在開啟列表中,把它新增進去。把當前格作為這一格的父節點。記錄這一格的f,g,和h值。

​ * 如果它已經在開啟列表中,用g值為參考檢查新的路徑是否更好。更低的g值意味著更好的路徑。如果是這樣,就把這一格的父節點改成當前格,並且重新計算這一格的g和f值。如果你保持你的開啟列表按f值排序,改變之後你可能需要重新對開啟列表排序。

d) 停止,當你

​ * 把目標格新增進了關閉列表(註解),這時候路徑被找到,或者

​ * 沒有找到目標格,開啟列表已經空了。這時候,路徑不存在。

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

OI Tarjin演算法整理

其實,tarjan演算法的基礎是dfs。我們準備兩個陣列low和dfn。low陣列是乙個標記陣列,記錄該點所在的強連通子圖所在搜尋子樹的根節點的dfn值 很繞嘴,往下看你就會明白 dfn陣列記錄搜尋到該點的時間,也就是第幾個搜尋這個點的。根據以下幾條規則,經過搜尋遍歷該圖 無需回溯 和對棧的操作,我...

排序演算法整理

template void cinsertsort mysort function compare template void cselectsort mysort function compare swap datas i datas id void cshellsort mysort funct...

程式設計演算法整理

演算法一 快速排序演算法 快速排序是由東尼 霍爾所發展的一種排序演算法。在平均狀況下,排序 n 個專案要 n log n 次比較。在最壞狀況下則需要 n2 次比較,但這種狀況並不常見。事實上,快速排序通常明顯比其他 n log n 演算法更快,因為它的內部迴圈 inner loop 可以在大部分的架...