導航:首頁 > 源碼編譯 > a演算法改進演算法及其應用

a演算法改進演算法及其應用

發布時間:2022-06-07 12:17:25

⑴ A*演算法現實應用的實際意義

A*演算法在人工智慧中是一種典型的啟發式搜索演算法,為了說清楚A*演算法,我看還是先說說何謂啟發式演算法。

一、何謂啟發式搜索演算法

在說它之前先提提狀態空間搜索。狀態空間搜索,如果按專業點的說法就是將問題求解過程表現為從初始狀態到目標狀態尋找這個路徑的過程。通俗點說,就是在解一個問題時,找到一條解題的過程可以從求解的開始到問題的結果(好象並不通俗哦)。由於求解問題的過程中分枝有很多,主要是求解過程中求解條件的不確定性,不完備性造成的,使得求解的路徑很多這就構成了一個圖,我們說這個圖就是狀態空間。問題的求解實際上就是在這個圖中找到一條路徑可以從開始到結果。這個尋找的過程就是狀態空間搜索。

常用的狀態空間搜索有深度優先和廣度優先。廣度優先是從初始狀態一層一層向下找,直到找到目標為止。深度優先是按照一定的順序前查找完一個分支,再查找另一個分支,以至找到目標為止。這兩種演算法在數據結構書中都有描述,可以參看這些書得到更詳細的解釋。

前面說的廣度和深度優先搜索有一個很大的缺陷就是他們都是在一個給定的狀態空間中窮舉。這在狀態空間不大的情況下是很合適的演算法,可是當狀態空間十分大,且不預測的情況下就不可取了。他的效率實在太低,甚至不可完成。在這里就要用到啟發式搜索了。

啟發式搜索就是在狀態空間中的搜索對每一個搜索的位置進行評估,得到最好的位置,再從這個位置進行搜索直到目標。這樣可以省略大量無畏的搜索路徑,提到了效率。在啟發式搜索中,對位置的估價是十分重要的。採用了不同的估價可以有不同的效果。我們先看看估價是如何表示的。

啟發中的估價是用估價函數表示的,如:

f(n) = g(n) + h(n)

其中f(n)是節點n的估價函數,g(n)實在狀態空間中從初始節點到n節點的實際代價,h(n)是從n到目標節點最佳路徑的估計代價。在這里主要是h(n)體現了搜索的啟發信息,因為g(n)是已知的。如果說詳細點,g(n)代表了搜索的廣度的優先趨勢。但是當h(n)>>g(n)時,可以省略g(n),而提高效率。這些就深了,不懂也不影響啦!我們繼續看看何謂A*演算法。

二、初識A*演算法

啟發式搜索其實有很多的演算法,比如:局部擇優搜索法、最好優先搜索法等等。當然A*也是。這些演算法都使用了啟發函數,但在具體的選取最佳搜索節點時的策略不同。象局部擇優搜索法,就是在搜索的過程中選取「最佳節點」後舍棄其他的兄弟節點,父親節點,而一直得搜索下去。這種搜索的結果很明顯,由於舍棄了其他的節點,可能也把最好的節點都舍棄了,因為求解的最佳節點只是在該階段的最佳並不一定是全局的最佳。最好優先就聰明多了,他在搜索時,便沒有舍棄節點(除非該節點是死節點),在每一步的估價中都把當前的節點和以前的節點的估價值比較得到一個「最佳的節點」。這樣可以有效的防止「最佳節點」的丟失。那麼A*演算法又是一種什麼樣的演算法呢?其實A*演算法也是一種最好優先的演算法。只不過要加上一些約束條件罷了。由於在一些問題求解時,我們希望能夠求解出狀態空間搜索的最短路徑,也就是用最快的方法求解問題,A*就是干這種事情的!我們先下個定義,如果一個估價函數可以找出最短的路徑,我們稱之為可採納性。A*演算法是一個可採納的最好優先演算法。A*演算法的估價函數可表示為:

f'(n) = g'(n) + h'(n)

這里,f'(n)是估價函數,g'(n)是起點到終點的最短路徑值,h'(n)是n到目標的最斷路經的啟發值。由於這個f'(n)其實是無法預先知道的,所以我們用前面的估價函數f(n)做近似。g(n)代替g'(n),但g(n)>=g'(n)才可(大多數情況下都是滿足的,可以不用考慮),h(n)代替h'(n),但h(n)<=h'(n)才可(這一點特別的重要)。可以證明應用這樣的估價函數是可以找到最短路徑的,也就是可採納的。我們說應用這種估價函數的最好優先演算法就是A*演算法。哈!你懂了嗎?肯定沒懂!接著看!

舉一個例子,其實廣度優先演算法就是A*演算法的特例。其中g(n)是節點所在的層數,h(n)=0,這種h(n)肯定小於h'(n),所以由前述可知廣度優先演算法是一種可採納的。實際也是。當然它是一種最臭的A*演算法。

再說一個問題,就是有關h(n)啟發函數的信息性。h(n)的信息性通俗點說其實就是在估計一個節點的值時的約束條件,如果信息越多或約束條件越多則排除的節點就越多,估價函數越好或說這個演算法越好。這就是為什麼廣度優先演算法的那麼臭的原因了,誰叫它的h(n)=0,一點啟發信息都沒有。但在游戲開發中由於實時性的問題,h(n)的信息越多,它的計算量就越大,耗費的時間就越多。就應該適當的減小h(n)的信息,即減小約束條件。但演算法的准確性就差了,這里就有一個平衡的問題。

⑵ 搜索演算法中,A演算法A*演算法的區別(急)

a*演算法:a*(a-star)演算法是一種靜態路網中求解最短路徑最有效的直接搜索方法。估價值與實際值越接近,估價函數取得就越好
a*
(a-star)演算法是一種靜態路網中求解最短路最有效的直接搜索方法。
注意是最有效的直接搜索演算法。之後涌現了很多預處理演算法(alt,ch,hl等等),在線查詢效率是a*演算法的數千甚至上萬倍。
公式表示為:
f(n)=g(n)+h(n),
其中
f(n)
是從初始點經由節點n到目標點的估價函數,
g(n)
是在狀態空間中從初始節點到n節點的實際代價,
h(n)
是從n到目標節點最佳路徑的估計代價。
保證找到最短路徑(最優解的)條件,關鍵在於估價函數f(n)的選取:
估價值h(n)<=
n到目標節點的距離實際值,這種情況下,搜索的點數多,搜索范圍大,效率低。但能得到最優解。並且如果h(n)=d(n),即距離估計h(n)等於最短距離,那麼搜索將嚴格沿著最短路徑進行,
此時的搜索效率是最高的。
如果
估價值>實際值,搜索的點數少,搜索范圍小,效率高,但不能保證得到最優解。

⑶ A*演算法的其它演算法

啟發式搜索其實有很多的演算法
比如:局部擇優搜索法、最好優先搜索法等等。當然A*也是。這些演算法都使用了啟發函數,但在具體的選取最佳搜索節點時的策略不同。像局部擇優搜索法,就是在搜索的過程中選取「最佳節點」後舍棄其他的兄弟節點,父親節點,而一直得搜索下去。這種搜索的結果很明顯,由於舍棄了其他的節點,可能也把最好的節點都舍棄了,因為求解的最佳節點只是在該階段的最佳並不一定是全局的最佳。最好優先就聰明多了,他在搜索時,並沒有舍棄節點(除非該節點是死節點),在每一步的估價中都把當前的節點和以前的節點的估價值比較得到一個「最佳的節點」。這樣可以有效的防止「最佳節點」的丟失。那麼A*演算法又是一種什麼樣的演算法呢?

⑷ A*演算法的實際運用

估價值與實際值越接近,估價函數取得就越好
例如對於幾何路網來說,可以取兩節點間曼哈頓距離做為估價值,即f=g(n) + (abs(dx - nx) + abs(dy - ny));這樣估價函數f在g值一定的情況下,會或多或少的受估價值h的制約,節點距目標點近,h值小,f值相對就小,能保證最短路的搜索向終點的方向進行。明顯優於Dijkstra演算法的毫無方向的向四周搜索。
conditions of heuristic
Optimistic (must be less than or equal to the real cost)
As close to the real cost as possible
詳細內容:
創建兩個表,OPEN表保存所有已生成而未考察的節點,CLOSED表中記錄已訪問過的節點。
算起點的估價值;
將起點放入OPEN表; while(OPEN!=NULL){從OPEN表中取估價值f(n)最小的節點n;if(n節點==目標節點)break;for(當前節點n的每個子節點X){算X的估價值;if(XinOPEN)if(X的估價值小於OPEN表的估價值){把n設置為X的父親;更新OPEN表中的估價值;//取最小路徑的估價值}if(XinCLOSE)continue;if(Xnotinboth){把n設置為X的父親;求X的估價值;並將X插入OPEN表中;//還沒有排序}}//endfor將n節點插入CLOSE表中;按照估價值將OPEN表中的節點排序;//實際上是比較OPEN表內節點f的大小,從最小路徑的節點向下進行。}//endwhile(OPEN!=NULL)保存路徑,即從終點開始,每個節點沿著父節點移動直至起點,這就是你的路徑;
用C語言實現A*最短路徑搜索演算法 ,作者 Tittup frog(跳跳蛙)。 #include<stdio.h>#include<math.h>#defineMaxLength100//用於優先隊列(Open表)的數組#defineHeight15//地圖高度#defineWidth20//地圖寬度#defineReachable0//可以到達的結點#defineBar1//障礙物#definePass2//需要走的步數#defineSource3//起點#defineDestination4//終點#defineSequential0//順序遍歷#defineNoSolution2//無解決方案#defineInfinity0xfffffff#defineEast(1<<0)#defineSouth_East(1<<1)#defineSouth(1<<2)#defineSouth_West(1<<3)#defineWest(1<<4)#defineNorth_West(1<<5)#defineNorth(1<<6)#defineNorth_East(1<<7)typedefstruct{signedcharx,y;}Point;constPointdir[8]={{0,1},//East{1,1},//South_East{1,0},//South{1,-1},//South_West{0,-1},//West{-1,-1},//North_West{-1,0},//North{-1,1}//North_East};unsignedcharwithin(intx,inty){return(x>=0&&y>=0&&x<Height&&y<Width);}typedefstruct{intx,y;unsignedcharreachable,sur,value;}MapNode;typedefstructClose{MapNode*cur;charvis;structClose*from;floatF,G;intH;}Close;typedefstruct//優先隊列(Open表){intlength;//當前隊列的長度Close*Array[MaxLength];//評價結點的指針}Open;staticMapNodegraph[Height][Width];staticintsrcX,srcY,dstX,dstY;//起始點、終點staticCloseclose[Height][Width];//優先隊列基本操作voidinitOpen(Open*q)//優先隊列初始化{q->length=0;//隊內元素數初始為0}voidpush(Open*q,Closecls[Height][Width],intx,inty,floatg){//向優先隊列(Open表)中添加元素Close*t;inti,mintag;cls[x][y].G=g;//所添加節點的坐標cls[x][y].F=cls[x][y].G+cls[x][y].H;q->Array[q->length++]=&(cls[x][y]);mintag=q->length-1;for(i=0;i<q->length-1;i++){if(q->Array[i]->F<q->Array[mintag]->F){mintag=i;}}t=q->Array[q->length-1];q->Array[q->length-1]=q->Array[mintag];q->Array[mintag]=t;//將評價函數值最小節點置於隊頭}Close*shift(Open*q){returnq->Array[--q->length];}//地圖初始化操作voidinitClose(Closecls[Height][Width],intsx,intsy,intdx,intdy){//地圖Close表初始化配置inti,j;for(i=0;i<Height;i++){for(j=0;j<Width;j++){cls[i][j].cur=&graph[i][j];//Close表所指節點cls[i][j].vis=!graph[i][j].reachable;//是否被訪問cls[i][j].from=NULL;//所來節點cls[i][j].G=cls[i][j].F=0;cls[i][j].H=abs(dx-i)+abs(dy-j);//評價函數值}}cls[sx][sy].F=cls[sx][sy].H;//起始點評價初始值//cls[sy][sy].G=0;//移步花費代價值cls[dx][dy].G=Infinity;}voidinitGraph(constintmap[Height][Width],intsx,intsy,intdx,intdy){//地圖發生變化時重新構造地inti,j;srcX=sx;//起點X坐標srcY=sy;//起點Y坐標dstX=dx;//終點X坐標dstY=dy;//終點Y坐標for(i=0;i<Height;i++){for(j=0;j<Width;j++){graph[i][j].x=i;//地圖坐標Xgraph[i][j].y=j;//地圖坐標Ygraph[i][j].value=map[i][j];graph[i][j].reachable=(graph[i][j].value==Reachable);//節點可到達性graph[i][j].sur=0;//鄰接節點個數if(!graph[i][j].reachable){continue;}if(j>0){if(graph[i][j-1].reachable)//left節點可以到達{graph[i][j].sur|=West;graph[i][j-1].sur|=East;}if(i>0){if(graph[i-1][j-1].reachable&&graph[i-1][j].reachable&&graph[i][j-1].reachable)//up-left節點可以到達{graph[i][j].sur|=North_West;graph[i-1][j-1].sur|=South_East;}}}if(i>0){if(graph[i-1][j].reachable)//up節點可以到達{graph[i][j].sur|=North;graph[i-1][j].sur|=South;}if(j<Width-1){if(graph[i-1][j+1].reachable&&graph[i-1][j].reachable&&map[i][j+1]==Reachable)//up-right節點可以到達{graph[i][j].sur|=North_East;graph[i-1][j+1].sur|=South_West;}}}}}}intbfs(){inttimes=0;inti,curX,curY,surX,surY;unsignedcharf=0,r=1;Close*p;Close*q[MaxLength]={&close[srcX][srcY]};initClose(close,srcX,srcY,dstX,dstY);close[srcX][srcY].vis=1;while(r!=f){p=q[f];f=(f+1)%MaxLength;curX=p->cur->x;curY=p->cur->y;for(i=0;i<8;i++){if(!(p->cur->sur&(1<<i))){continue;}surX=curX+dir[i].x;surY=curY+dir[i].y;if(!close[surX][surY].vis){close[surX][surY].from=p;close[surX][surY].vis=1;close[surX][surY].G=p->G+1;q[r]=&close[surX][surY];r=(r+1)%MaxLength;}}times++;}returntimes;}intastar(){//A*演算法遍歷//inttimes=0;inti,curX,curY,surX,surY;floatsurG;Openq;//Open表Close*p;initOpen(&q);initClose(close,srcX,srcY,dstX,dstY);close[srcX][srcY].vis=1;push(&q,close,srcX,srcY,0);while(q.length){//times++;p=shift(&q);curX=p->cur->x;curY=p->cur->y;if(!p->H){returnSequential;}for(i=0;i<8;i++){if(!(p->cur->sur&(1<<i))){continue;}surX=curX+dir[i].x;surY=curY+dir[i].y;if(!close[surX][surY].vis){close[surX][surY].vis=1;close[surX][surY].from=p;surG=p->G+sqrt((curX-surX)*(curX-surX)+(curY-surY)*(curY-surY));push(&q,close,surX,surY,surG);}}}//printf(times:%d ,times);returnNoSolution;//無結果}constintmap[Height][Width]={{0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,1,1},{0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1},{0,0,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,1},{0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,1},{0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,1,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0},{0,0,0,0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0},{0,1,0,0,0,0,1,0,0,0,0,0,0,1,0,1,0,0,0,1},{0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0}};constcharSymbol[5][3]={□,▓,▽,☆,◎};voidprintMap(){inti,j;for(i=0;i<Height;i++){for(j=0;j<Width;j++){printf(%s,Symbol[graph[i][j].value]);}puts();}puts();}Close*getShortest(){//獲取最短路徑intresult=astar();Close*p,*t,*q=NULL;switch(result){caseSequential://順序最近p=&(close[dstX][dstY]);while(p)//轉置路徑{t=p->from;p->from=q;q=p;p=t;}close[srcX][srcY].from=q->from;return&(close[srcX][srcY]);caseNoSolution:returnNULL;}returnNULL;}staticClose*start;staticintshortestep;intprintShortest(){Close*p;intstep=0;p=getShortest();start=p;if(!p){return0;}else{while(p->from){graph[p->cur->x][p->cur->y].value=Pass;printf((%d,%d)→ ,p->cur->x,p->cur->y);p=p->from;step++;}printf((%d,%d) ,p->cur->x,p->cur->y);graph[srcX][srcY].value=Source;graph[dstX][dstY].value=Destination;returnstep;}}voidclearMap(){//ClearMapMarksofStepsClose*p=start;while(p){graph[p->cur->x][p->cur->y].value=Reachable;p=p->from;}graph[srcX][srcY].value=map[srcX][srcY];graph[dstX][dstY].value=map[dstX][dstY];}voidprintDepth(){inti,j;for(i=0;i<Height;i++){for(j=0;j<Width;j++){if(map[i][j]){printf(%s,Symbol[graph[i][j].value]);}else{printf(%2.0lf,close[i][j].G);}}puts();}puts();}voidprintSur(){inti,j;for(i=0;i<Height;i++){for(j=0;j<Width;j++){printf(%02x,graph[i][j].sur);}puts();}puts();}voidprintH(){inti,j;for(i=0;i<Height;i++){for(j=0;j<Width;j++){printf(%02d,close[i][j].H);}puts();}puts();}intmain(intargc,constchar**argv){initGraph(map,0,0,0,0);printMap();while(scanf(%d%d%d%d,&srcX,&srcY,&dstX,&dstY)!=EOF){if(within(srcX,srcY)&&within(dstX,dstY)){if(shortestep=printShortest()){printf(從(%d,%d)到(%d,%d)的最短步數是:%d ,srcX,srcY,dstX,dstY,shortestep);printMap();clearMap();bfs();//printDepth();puts((shortestep==close[dstX][dstY].G)?正確:錯誤);clearMap();}else{printf(從(%d,%d)不可到達(%d,%d) ,srcX,srcY,dstX,dstY);}}else{puts(輸入錯誤!);}}return(0);}

⑸ pdiibq 改進A_Star演算法

//程序需要一個輸入文件,名稱必須為 in.txt
//A_Star演算法是個很有名的演算法,從程序競賽,到網路選擇,到游戲設計都有很大的應用
//我將A_Star演算法做了一點小小的改進(但不知道這個改進以前有沒有人做過)用來算迷宮。
//主要的改動是首先判斷G(n)是否足夠小,如果足夠小則直接放棄向前搜索,因為已經有過更短的路徑穿過這個點了
//網上的演算法都是使用F(n)=G(n)+H(n)來判斷該選擇那個方向的下一步,而沒有驗證G(n)是否足夠小

#include <stdio.h>
#include <string.h>
#include <math.h>
const unsigned int Largest=~0; //無符號int的最大值

struct Step //步
{
unsigned int X,Y;
unsigned char ZhuBin;
};
unsigned char Detect[9]={1<<7,1<<6,1<<5,1<<4,1<<3,1<<2,1<<1,1<<0,0xFF}; //探針

char **Maze; //原始迷宮
unsigned int SizeX,SizeY; //迷宮尺寸
unsigned int StartX,StartY; //起點
unsigned int EndX,EndY; //終點

Step *WorkPath; //工作棧
char *StepKind; //表示前進的步是斜向還是橫豎向,以便縮減步長
unsigned int WorkLenth,Length; //總步數與總步長

char **ResultMaze; //結果迷宮
unsigned int ResultLength; //最短步長和

unsigned int **GDistance,**HDistance; //輔助表,這個是關鍵

int MoveX[8]={0,1,1,1,0,-1,-1,-1},MoveY[8]={-1,-1,0,1,1,1,0,-1}; //偏移量

int Read(char pFileName[])
{
FILE *pFile;
if( (pFile=fopen(pFileName,"r")) == 0)
{
printf("不能打開文件 %s\n",pFileName);
return 0;
}

fscanf(pFile,"%d %d",&SizeX,&SizeY);
fscanf(pFile,"%d %d",&StartX,&StartY);
fscanf(pFile,"%d %d",&EndX,&EndY);

unsigned int i,j;
WorkPath=new Step[SizeX*SizeY+1];//動態一維分配工作棧
StepKind=new char[SizeX*SizeY+1];

Maze=new char *[SizeY+1]; //動態二維分配迷宮與輔助表
GDistance=new unsigned int *[SizeY+1];
HDistance=new unsigned int *[SizeY+1];
ResultMaze=new char *[SizeY+1];
for(j=1;j<=SizeY;j++)
{
Maze[j]=new char [SizeX+1];
GDistance[j]=new unsigned int [SizeX+1];
HDistance[j]=new unsigned int [SizeX+1];
ResultMaze[j]=new char [SizeX+1];
}

fgetc(pFile);
for(j=1;j<=SizeY;j++)
{
for(i=1;i<=SizeX;i++)
{
ResultMaze[j][i]=(Maze[j][i]=fgetc(pFile)-'0');
GDistance[j][i]=Largest;
HDistance[j][i]=(unsigned int)(sqrt((i-EndX)*(i-EndX)+(j-EndY)*(j-EndY))*5.0);
}
fgetc(pFile);
}
fclose(pFile);
return 1;
}

int OutTable_F(char **p,char pFileName[])
{
FILE *pFile;
if( (pFile=fopen(pFileName,"w")) == 0)
return 0;
fprintf(pFile,"迷宮程序,採用自己改進的A_Star演算法。作者:朱斌 [email protected]\n");
fprintf(pFile,"\n");
unsigned int i,j;
for(i=1 ; i<=SizeX+2 ; i++)
fprintf(pFile,"■");
fprintf(pFile,"\n");
for(j=1;j<=SizeY;j++)
{
fprintf(pFile,"■");
for(i=1;i<=SizeX;i++)
{
if(p[j][i]==0)
fprintf(pFile," ");
else if(p[j][i]==1)
fprintf(pFile,"■");
else
fprintf(pFile,"⊙");
}
fprintf(pFile,"■");
fprintf(pFile,"\n");
}
for(i=1 ; i<=SizeX+2 ; i++)
fprintf(pFile,"■");
fprintf(pFile,"\n");
fclose(pFile);
return 1;
}

⑹ A*演算法用於路徑規劃,有什麼缺點

缺點:A*演算法通過比較當前路徑柵格的8個鄰居的啟發式函數值F來逐步確定下一個路徑柵格,當存在多個最小值時A*演算法不能保證搜索的路徑最優。
A*演算法;A*(A-Star)演算法是一種靜態路網中求解最短路徑最有效的直接搜索方法。估價值與實際值越接近,估價函數取得就越好。A*[1] (A-Star)演算法是一種靜態路網中求解最短路最有效的直接搜索方法。注意是最有效的直接搜索演算法。之後涌現了很多預處理演算法(ALT,CH,HL等等),在線查詢效率是A*演算法的數千甚至上萬倍。公式表示為: f(n)=g(n)+h(n),其中 f(n) 是從初始點經由節點n到目標點的估價函數,g(n) 是在狀態空間中從初始節點到n節點的實際代價,h(n) 是從n到目標節點最佳路徑的估計代價。保證找到最短路徑(最優解的)條件,關鍵在於估價函數f(n)的選取:估價值h(n)<= n到目標節點的距離實際值,這種情況下,搜索的點數多,搜索范圍大,效率低。但能得到最優解。並且如果h(n)=d(n),即距離估計h(n)等於最短距離,那麼搜索將嚴格沿著最短路徑進行, 此時的搜索效率是最高的。如果 估價值>實際值,搜索的點數少,搜索范圍小,效率高,但不能保證得到最優解。

⑺ A*演算法的好處

其實A*演算法也是一種最好優先的演算法
只不過要加上一些約束條件罷了。由於在一些問題求解時,我們希望能夠求解出狀態空間搜索的最短路徑,也就是用最快的方法求解問題,A*就是干這種事情的!
我們先下個定義,如果一個估價函數可以找出最短的路徑,我們稱之為可採納性。A*演算法是一個可採納的最好優先演算法。A*演算法的估價函數可表示為:
f'(n) = g'(n) + h'(n)
這里,f'(n)是估價函數,g'(n)是起點到節點n的最短路徑值,h'(n)是n到目標的最短路經的啟發值。由於這個f'(n)其實是無法預先知道的,所以我們用前面的估價函數f(n)做近似。g(n)代替g'(n),但 g(n)>=g'(n)才可(大多數情況下都是滿足的,可以不用考慮),h(n)代替h'(n),但h(n)<=h'(n)才可(這一點特別的重要)。可以證明應用這樣的估價函數是可以找到最短路徑的,也就是可採納的。我們說應用這種估價函數的最好優先演算法就是A*演算法。
舉一個例子,其實廣度優先演算法就是A*演算法的特例。其中g(n)是節點所在的層數,h(n)=0,這種h(n)肯定小於h'(n),所以由前述可知廣度優先演算法是一種可採納的。實際也是。當然它是一種最臭的A*演算法。
再說一個問題,就是有關h(n)啟發函數的信息性。h(n)的信息性通俗點說其實就是在估計一個節點的值時的約束條件,如果信息越多或約束條件越多則排除的節點就越多,估價函數越好或說這個演算法越好。這就是為什麼廣度優先演算法的那麼臭的原因了,誰叫它的h(n)=0,一點啟發信息都沒有。但在游戲開發中由於實時性的問題,h(n)的信息越多,它的計算量就越大,耗費的時間就越多。就應該適當的減小h(n)的信息,即減小約束條件。但演算法的准確性就差了,這里就有一個平衡的問題。

⑻ 什麼是 a演算法a* 演算法有什麼特點

A*演算法:A*(A-Star)演算法是一種靜態路網中求解最短路徑最有效的直接搜索方法。估價值與實際值越接近,估價函數取得就越好
A* (A-Star)演算法是一種靜態路網中求解最短路最有效的直接搜索方法。
注意是最有效的直接搜索演算法。之後涌現了很多預處理演算法(ALT,CH,HL等等),在線查詢效率是A*演算法的數千甚至上萬倍。
公式表示為: f(n)=g(n)+h(n),
其中 f(n) 是從初始點經由節點n到目標點的估價函數,
g(n) 是在狀態空間中從初始節點到n節點的實際代價,
h(n) 是從n到目標節點最佳路徑的估計代價。
保證找到最短路徑(最優解的)條件,關鍵在於估價函數f(n)的選取:
估價值h(n)<= n到目標節點的距離實際值,這種情況下,搜索的點數多,搜索范圍大,效率低。但能得到最優解。並且如果h(n)=d(n),即距離估計h(n)等於最短距離,那麼搜索將嚴格沿著最短路徑進行, 此時的搜索效率是最高的。
如果 估價值>實際值,搜索的點數少,搜索范圍小,效率高,但不能保證得到最優解。

⑼ A*演算法如何改進

十萬火急:此改進的模糊C-此函數實現遺傳演算法,用於模糊C-均值聚類 %% A=farm(:,Ser(1)); B=farm(:,Ser(2)); P0=unidrnd(M-1); a=[

閱讀全文

與a演算法改進演算法及其應用相關的資料

熱點內容
華為mml命令查看用戶量 瀏覽:905
場論朗道pdf 瀏覽:369
如何使用qtquick編譯器 瀏覽:46
山西高配伺服器雲伺服器 瀏覽:740
為什麼編譯按f9沒反應 瀏覽:118
購物app都適合買什麼東西 瀏覽:273
savetxt函數python 瀏覽:573
編譯器小端改大端 瀏覽:638
華為安卓哪些文件夾能刪除 瀏覽:402
手機samp伺服器地址 瀏覽:205
phpformat函數 瀏覽:563
單片機由線 瀏覽:591
如何查找方舟編譯過的app 瀏覽:897
青山有什麼做演算法的公司 瀏覽:568
硬體編譯原理圖 瀏覽:162
程序員技術總監 瀏覽:72
程序員網易雲報告 瀏覽:463
studio編譯功能在哪裡 瀏覽:242
空氣壓縮機尺寸 瀏覽:988
sockethttpsphp 瀏覽:488