
經典算法研究系列:一、A*搜索算法
啟發式搜索算法
要理解A*搜尋算法,還得從啟發式搜索算法開始談起。
所謂啟發式搜索,就在于當前搜索結點往下選擇下一步結點時,可以通過一個啟發函數來進行選擇,選擇代價最少的結點作為下一步搜索結點而跳轉其上(遇到有一個以上代價最少的結點,不妨選距離當前搜索點最近一次展開的搜索點進行下一步搜索)。
DFS和BFS在展開子結點時均屬于盲目型搜索,也就是說,它不會選擇哪個結點在下一次搜索中更優而去跳轉到該結點進行下一步的搜索。在運氣不好的情形中,均需要試探完整個解集空間, 顯然,只能適用于問題規模不大的搜索問題中。
而與DFS,BFS不同的是,一個經過仔細設計的啟發函數,往往在很快的時間內就可得到一個搜索問題的最優解,對于NP問題,亦可在多項式時間內得到一個較優解。是的,關鍵就是如何設計這個啟發函數。
A*搜尋算法
A*搜尋算法,俗稱A星算法,作為啟發式搜索算法中的一種,這是一種在圖形平面上,有多個節點的路徑,求出最低通過成本的算法。常用于游戲中的NPC的移動計算,或線上游戲的BOT的移動計算上。該算法像Dijkstra算法一樣,可以找到一條最短路徑;也像BFS一樣,進行啟發式的搜索。
A*算法最為核心的部分,就在于它的一個估值函數的設計上:
f(n)=g(n)+h(n)
其中f(n)是每個可能試探點的估值,它有兩部分組成:
一部分,為g(n),它表示從起始搜索點到當前點的代價(通常用某結點在搜索樹中的深度來表示)。
另一部分,即h(n),它表示啟發式搜索中最為重要的一部分,即當前結點到目標結點的估值,
h(n)設計的好壞,直接影響著具有此種啟發式函數的啟發式算法的是否能稱為A*算法。
一種具有f(n)=g(n)+h(n)策略的啟發式算法能成為A*算法的充分條件是:
1、搜索樹上存在著從起始點到終了點的最優路徑。
2、問題域是有限的。
3、所有結點的子結點的搜索代價值>0。
4、h(n)=<h*(n) (h*(n)為實際問題的代價值)。
當此四個條件都滿足時,一個具有f(n)=g(n)+h(n)策略的啟發式算法能成為A*算法,并一定能找到最優解。
對于一個搜索問題,顯然,條件1,2,3都是很容易滿足的,而條件4: h(n)<=h*(n)是需要精心設計的,由于h*(n)顯然是無法知道的,所以,一個滿足條件4的啟發策略h(n)就來的難能可貴了。
不過,對于圖的最優路徑搜索和八數碼問題,有些相關策略h(n)不僅很好理解,而且已經在理論上證明是滿足條件4的,從而為這個算法的推廣起到了決定性的作用。
且h(n)距離h*(n)的呈度不能過大,否則h(n)就沒有過強的區分能力,算法效率并不會很高。對一個好的h(n)的評價是:h(n)在h*(n)的下界之下,并且盡量接近h*(n)。
A*搜尋算法的實現
先舉一個小小的例子:即求V0->V5的路徑,V0->V5的過程中,可以經由V1,V2,V3,V4各點達到目的點V5。下面的問題,即是求此起始頂點V0->途徑任意頂點V1、V2、V3、V4->目標頂點V5的最短路徑。
//圖片是引用rickone 的。上圖中,說白了,無非就是:一個隊列,open 往close 插入元素。
通過上圖,我們可以看出::A*算法最為核心的過程,就在每次選擇下一個當前搜索點時,是從所有已探知的但未搜索過點中(可能是不同層,亦可不在同一條支路上),選取f值最小的結點進行展開。
而所有“已探知的但未搜索過點”可以通過一個按f值升序的隊列(即優先隊列)進行排列。
這樣,在整體的搜索過程中,只要按照類似廣度優先的算法框架,從優先隊列中彈出隊首元素(f值),對其可能子結點計算g、h和f值,直到優先隊列為空(無解)或找到終止點為止。
A*算法與廣度、深度優先和Dijkstra 算法的聯系就在于:當g(n)=0時,該算法類似于DFS,當h(n)=0時,該算法類似于BFS。且同時,如果h(n)為0,只需求出g(n),即求出起點到任意頂點n的最短路徑,則轉化為單源最短路徑問題,即Dijkstra算法。這一點,可以通過上面的A*搜索樹的具體過程中將h(n)設為0或將g(n)設為0而得到。
A*算法流程:
首先將起始結點S放入OPEN表,CLOSE表置空,算法開始時:
1、如果OPEN表不為空,從表頭取一個結點n,如果為空算法失敗。
2、n是目標解嗎?是,找到一個解(繼續尋找,或終止算法)。
3、將n的所有后繼結點展開,就是從n可以直接關聯的結點(子結點),如果不在CLOSE表中,就將它們放入OPEN表,并把S放入CLOSE表,同時計算每一個后繼結點的估價值f(n),將OPEN表按f(x)排序,最小的放在表頭,重復算法,回到1。
//OPEN-->CLOSE,起點-->任意頂點g(n)-->目標頂點h(n)
closedset := the empty set //已經被估算的節點集合
openset := set containing the initial node //將要被估算的節點集合
g_score[start] := 0 //g(n)
h_score[start] := heuristic_estimate_of_distance(start, goal) //h(n)
f_score[start] := h_score[start]
while openset is not empty //若OPEN表不為空
x := the node in openset having the lowest f_score[] value //x為OPEN表中最小的
if x = goal //如果x是一個解
return reconstruct_path(came_from,goal) //
remove x from openset
add x to closedset //x放入
CLSOE表
for each y in neighbor_nodes(x)
if y in closedset
continue
tentative_g_score := g_score[x] + dist_between(x,y)
if y not in openset
add y to openset
tentative_is_better := true
else if tentative_g_score < g_score[y]
tentative_is_better := true
else
tentative_is_better := false
if tentative_is_better = true
came_from[y] := x
g_score[y] := tentative_g_score
h_score[y] := heuristic_estimate_of_distance(y, goal) //x-->y-->goal
f_score[y] := g_score[y] + h_score[y]
return failure
function reconstruct_path(came_from,current_node)
if came_from[current_node] is set
p = reconstruct_path(came_from,came_from[current_node])
return (p + current_node)
else
return the empty path
與結點寫在一起的數值表示那個結點的價值f(n),當OPEN表為空時CLOSE表中將求得從V0到其它所有結點的最短路徑。
考慮到算法性能,外循環中每次從OPEN表取一個元素,共取了n次(共n個結點),每次展開一個結點的后續結點時,需O(n)次,同時再對OPEN表做一次排序,OPEN表大小是O(n)量級的,若用快排就是O(nlogn),乘以外循環總的復雜度是O(n^2 * logn),
如果每次不是對OPEN表進行排序,因為總是不斷地有新的結點添加進來,所以不用進行排序,而是每次從OPEN表中求一個最小的,那只需要O(n)的復雜度,所以總的復雜度為O(n*n),這相當于Dijkstra算法。
本文完。
July、二零一一年二月十日更新。
------------------------------------------------
后續:July、二零一一年三月一日更新。
簡述A*最短路徑算法的方法:
目標:從當前位置A到目標位置B找到一條最短的行走路徑。
方法:從A點開始,遍歷所有的可走路徑,記錄到一個結構中,記錄內容為(位置點,最小步數)
當任何第二次走到一個點的時候,判斷最小步驟是否小于記錄的內容,如果是,則更新掉原最小步數,一直到所有的路徑點都不能繼續都了為止,最終那個點被標注的最小步數既是最短路徑,
而反向找跟它相連的步數相繼少一個值的點連起來就形成了最短路徑,當多個點相同,則任意取一條即可。
總結:
A*算法實際是個窮舉算法,也與課本上教的最短路徑算法類似。課本上教的是兩頭往中間走,也是所有路徑都走一次,每一個點標注最短值。
數據分析咨詢請掃描二維碼
若不方便掃碼,搜微信號:CDAshujufenxi
2025 年,數據如同數字時代的 DNA,編碼著人類社會的未來圖景,驅動著商業時代的運轉。從全球互聯網用戶每天產生的2.5億TB數據, ...
2025-05-27CDA數據分析師證書考試體系(更新于2025年05月22日)
2025-05-26解碼數據基因:從數字敏感度到邏輯思維 每當看到超市貨架上商品的排列變化,你是否會聯想到背后的銷售數據波動?三年前在零售行 ...
2025-05-23在本文中,我們將探討 AI 為何能夠加速數據分析、如何在每個步驟中實現數據分析自動化以及使用哪些工具。 數據分析中的AI是什么 ...
2025-05-20當數據遇見人生:我的第一個分析項目 記得三年前接手第一個數據分析項目時,我面對Excel里密密麻麻的銷售數據手足無措。那些跳動 ...
2025-05-20在數字化運營的時代,企業每天都在產生海量數據:用戶點擊行為、商品銷售記錄、廣告投放反饋…… 這些數據就像散落的拼圖,而相 ...
2025-05-19在當今數字化營銷時代,小紅書作為國內領先的社交電商平臺,其銷售數據蘊含著巨大的商業價值。通過對小紅書銷售數據的深入分析, ...
2025-05-16Excel作為最常用的數據分析工具,有沒有什么工具可以幫助我們快速地使用excel表格,只要輕松幾步甚至輸入幾項指令就能搞定呢? ...
2025-05-15數據,如同無形的燃料,驅動著現代社會的運轉。從全球互聯網用戶每天產生的2.5億TB數據,到制造業的傳感器、金融交易 ...
2025-05-15大數據是什么_數據分析師培訓 其實,現在的大數據指的并不僅僅是海量數據,更準確而言是對大數據分析的方法。傳統的數 ...
2025-05-14CDA持證人簡介: 萬木,CDA L1持證人,某電商中廠BI工程師 ,5年數據經驗1年BI內訓師,高級數據分析師,擁有豐富的行業經驗。 ...
2025-05-13CDA持證人簡介: 王明月 ,CDA 數據分析師二級持證人,2年數據產品工作經驗,管理學博士在讀。 學習入口:https://edu.cda.cn/g ...
2025-05-12CDA持證人簡介: 楊貞璽 ,CDA一級持證人,鄭州大學情報學碩士研究生,某上市公司數據分析師。 學習入口:https://edu.cda.cn/g ...
2025-05-09CDA持證人簡介 程靖 CDA會員大咖,暢銷書《小白學產品》作者,13年頂級互聯網公司產品經理相關經驗,曾在百度、美團、阿里等 ...
2025-05-07相信很多做數據分析的小伙伴,都接到過一些高階的數據分析需求,實現的過程需要用到一些數據獲取,數據清洗轉換,建模方法等,這 ...
2025-05-06以下的文章內容來源于劉靜老師的專欄,如果您想閱讀專欄《10大業務分析模型突破業務瓶頸》,點擊下方鏈接 https://edu.cda.cn/g ...
2025-04-30CDA持證人簡介: 邱立峰 CDA 數據分析師二級持證人,數字化轉型專家,數據治理專家,高級數據分析師,擁有豐富的行業經驗。 ...
2025-04-29CDA持證人簡介: 程靖 CDA會員大咖,暢銷書《小白學產品》作者,13年頂級互聯網公司產品經理相關經驗,曾在百度,美團,阿里等 ...
2025-04-28CDA持證人簡介: 居瑜 ,CDA一級持證人國企財務經理,13年財務管理運營經驗,在數據分析就業和實踐經驗方面有著豐富的積累和經 ...
2025-04-27數據分析在當今信息時代發揮著重要作用。單因素方差分析(One-Way ANOVA)是一種關鍵的統計方法,用于比較三個或更多獨立樣本組 ...
2025-04-25