1. 程式人生 > >關於A*演算法的一點心得

關於A*演算法的一點心得

思路來源

https://blog.csdn.net/haolexiao/article/details/70302848

https://www.cnblogs.com/yyf0309/p/8438849.html

心得

啟發式搜尋,聽上去挺高階的,

這也是我入acm界一年多沒學這個,對其望而生畏的原因之一

 

實際上,就是有目的的搜尋,先選擇那些最有可能搜到答案的情況,

而dfs、bfs搜尋是盲目的暴力窮舉,雖然可以部分小剪枝,

但沒有很明顯的調整搜尋順序從而優化的思想在裡面。

 

比如最短路問題,如果我們當前從源點s走到了某個中間點i,實際花費為g(s->i),

那麼我們要從i再去終點e,理想花費為h(i->n),

那最短路的理想狀況就是g(s->i)+h(i->n)啦。

 

那麼在我們面前有多箇中轉點i時,

記g(n)=g(s->i),h(n)=h(i->n),

我們優先選擇g(n)+h(n)最小的點,是最優的。

 

其實質也是一種貪心思想,優先更新這些點,會使更新次數大大減少。

此時若選擇次優的點,某些點很可能需要鬆弛兩次以上,

而鬆弛最優點,只需要鬆弛一次。

 

以下各條摘自上述思路來源部落格,自己對其加點批註。

先考慮極端情況, 如果h(n)=0的情況下,只有g(n)起作用,那麼A*演算法就是Dijkstra演算法。①

若沒有評估函式h(n),則每步走的都是真實的,那我們直接選當前最短的去更新就好了。

如果h(n)始終小於等於實際n點到終點的距離,那麼必然能夠保證A*演算法找的解就是最優解。②

評估函式的情況往往比實際情況理想,我們對這些點抱有期望才去更新這些點。

h(n)越小,則A*擴充套件的節點也就越多,A*演算法執行的也就越慢。③

存在一個期望落差,需要用實際遍歷更多的點來確定新的g(n),來彌補期望落差。

如果h(n)始終都等於實際n點到終點的距離,那麼A*演算法只會嚴格走從起點到終點的最短路徑。

如果h(n)有時候大於實際n點到終點的距離,那麼不能保證A*演算法能夠找到最短路徑。④

顯然若h(n)大於實際距離,則我們誤將該距離認為理想可更新距離,對其進行更新,

其結果就是,最後過該點的路,被g(n)發現比實際距離大時,已經作為錯誤答案更新其它邊了。

另外一種極端情況,就是如果只有h(n)發揮作用,則A*演算法就相當於貪心演算法。⑤

對於未知,我們還是優先選擇那些看上去像是最短路的路,嘗試一下。

 

這個東西,可以變得更通俗易懂。

我在北京,想飛往紐約,直飛機票是10000元(g(終點))。

而北京飛東京,已經知道是3000元(g(i1)),東京飛紐約,專家估價8000元。(h(i1))。

北京飛西雅圖,已經知道是4000元(g(i2)),西雅圖飛底特律,專家估價2000元,底特律飛紐約,專家估價2000元。(h(i2))。

那我們先試試i2方案,即使最後不一定選擇該方案,最後的花銷還是按實際市場行情算的。

 

若能更新成功,我們會慶幸選了這麼一條路。

若不能,我們只是沒能因此更新其它路線而已。

最壞的影響,就是多搜了一波這條路上的這些點。

因此,專家的評估與真實值的貼近水平至關重要。

它決定著我們會能少搜多少點,起碼別多搜啊QAQ。

 

若專家估價給高了,本來東京飛紐約應該1000元的,是最短路,

結果估價8000元,因此沒能成為我們選擇的目標。

最終我們理想錯失最短路,選擇了一條別的看似最短的路更新,

更新出來的路,肯定不是最短路。