關於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元,因此沒能成為我們選擇的目標。
最終我們理想錯失最短路,選擇了一條別的看似最短的路更新,
更新出來的路,肯定不是最短路。