1、簡介算法
A*算法是啓發式算法的一種,能夠求出在圖形平面上有着多個節點時,找到兩個節點之間的最短路徑,它的用到的地方仍是挺多的,如遊戲中的NPC移動,其實A*算法和Dijkstra算法很像很像的(我的至關感受額,但也有一點點差別),若是你瞭解Dijkstra算法的話,那對於A*算法就很容易接受了。函數
2、算法主要內容性能
對於A*算法而言,須要設計一個估計函數,即f(n) = g(n) + h(n),其中g(n)表示搜索起點到當前節點的代價(一般用某節點在搜索樹中的深度來表示的),h(n)表示當前節點到目標節點的估計值,對於A*算法的估計函數而言,其中h(n)的設計最爲重要,也是衡量是否爲A*算法的一個標準。設計
對於A*算法而言,須要知足一下幾個條件纔算得上A*算法:3d
1).圖中存在從起點到目標終點的最有路徑。blog
2).問題是有限的。排序
3).全部節點的子節點代價>0。遊戲
4).h(n) =< h*(n) (其中h*(n)爲實際問題的代價值)搜索
3、算法實現示意圖遍歷
求V0->V5的路徑,在V0->V5過程當中,能夠通過V一、V二、V三、V4到達目標及誒大V5
4、算法設計僞代碼
將起點放入OPEN表;
while(OPEN!=NULL)
{
從OPEN表中取估價值f最小的節點n;
if(n節點==目標節點)
{
找到了目標
break;
}
for(當前節點n的每一個子節點X)
{
算X的估價值;
if(X in OPEN)
{
if( X的估價值小於OPEN表的估價值 )
{
把n設置爲X的父親;
更新OPEN表中的估價值; //取最小路徑的估價值
}
}
if(X in CLOSE)
{
continue;
}
if(X not in both)
{
把n設置爲X的父親;
求X的估價值;
並將X插入OPEN表中; //尚未排序
}
}//end for
將n節點插入CLOSE表中;
按照估價值將OPEN表中的節點排序; //其實是比較OPEN表內節點f的大小,從最小路徑的節點向下進行。
}//end while(OPEN!=NULL)
保存路徑,即從終點開始,每一個節點沿着父節點移動直至起點,這就是你的路徑
5、A*算法和Dijkstra算法比較
這兩個算法很類似,但通常A*算法的性能比Dijkstra算法好稍稍好一些,A*算法的時間複雜度爲nlog(n),而Dijkstra算法爲o(n2),這是由於在得到沒有遍歷的節點時,也就是在OPEN表中的那些,A*算法是對其用快速排序將其按照估計值的大小進行排序的,於是總時間複雜度爲o(n)*log(n),其中o(n)外層遍歷OPEN表的全部節點,但對於Dijkstra算法,它並無對那些OPEN表的節點進行排序,因此獲得的時間複雜度爲o(n)*o(n)。