導航:首頁 > 源碼編譯 > a演算法demo

a演算法demo

發布時間:2022-08-19 00:25:38

㈠ A*演算法java實現

首先,你要知道走迷宮的思路:就是遇到岔路都往一個方向,比如往右,遇到死路就回頭,回頭遇到岔路繼續往右。
線法線在同一平面上,反射光線與入射光線分

㈡ 用java編程,. 用方法實現輸入N個數,求這N個數的最大值和最少值,並輸出  a.實現輸入N

publicclassInputNumberDemo
{
/**
*接收輸入數字
*@paramcount輸入的個數
*@return
*/
publicint[]acceptInput(intcount)
{
int[]ret=newint[count];
Scannersc=newScanner(System.in);
Stringis=null;
booleanflag=Boolean.TRUE;
System.out.print("請輸入第1個數字:");
intindex=0;
while(flag)
{
is=sc.next();
if(null!=is&&!"".equals(is))
{
if("over".equals(is))
{
break;
}
else
{
ret[index]=Integer.valueOf(is);
index++;
if(index==count)
{
System.out.print("請輸入over結束[否則出下標越界異常咯!]:");
}
else
{
System.out.print("請輸入第"+(index+1)+"個數字:");
}
}

}
}
returnret;
}

/**
*求int數組中的最大值和最小值
*@paramnumArray
*@returnMaxMinVaueBean
*/
(int[]numArray)
{
MaxMinVaueBeanresult=null;
if(numArray!=null&&numArray.length>0)
{
result=newMaxMinVaueBean();
intmax=0;
intmin=0;
for(inti=0;i<numArray.length;i++)
{
if(i==0)
{
max=numArray[i];
min=numArray[i];
}
if(numArray[i]>max)
{
max=numArray[i];
}
if(numArray[i]<min)
{
min=numArray[i];
}
}
result.setMaxNumber(max);
result.setMinNumber(min);
}
returnresult;
}

publicvoidprintMaxAndMinValue(MaxMinVaueBeanvalueBean)
{
System.out.println(valueBean.toString());
}

/**
*封裝最大值和最小值的對象
*/
classMaxMinVaueBean
{
privateintmaxNumber;

privateintminNumber;

publicintgetMaxNumber(){
returnmaxNumber;
}

publicvoidsetMaxNumber(intmaxNumber){
this.maxNumber=maxNumber;
}

publicintgetMinNumber(){
returnminNumber;
}

publicvoidsetMinNumber(intminNumber){
this.minNumber=minNumber;
}

publicStringtoString()
{
return"最大值為:"+maxNumber+",最小值為:"+minNumber;
}

}

publicstaticvoidmain(String[]args)
{
InputNumberDemodemo=newInputNumberDemo();
//先調用接收輸入數字的函數,指定輸入6個
int[]inputArray=demo.acceptInput(6);
//調用求此6個數字的最大值和最小值的方法
MaxMinVaueBeanvalueBean=demo.getMaxAndMinValue(inputArray);
//列印最大值和最小值
demo.printMaxAndMinValue(valueBean);

}
}

上面這個類就可以實現你描述的功能,手寫的,望採納!

㈢ A*演算法的簡單案例

參見參考資料中的「A*演算法入門」
另外,A*同樣可以用於其他搜索問題。

㈣ 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-Star)演算法是一種靜態路網中求解最短路徑最有效的直接搜索方法。估價值與實際值越接近,估價函數取得就越好。

㈥ 什麼是A搜索演算法

A*搜索演算法,俗稱A星演算法,作為啟發式搜索演算法中的一種,這是一種在圖形平面上,有多個節點的路徑,求出最低通過成本的演算法。常用於游戲中的NPC的移動計算,或線上游戲的BOT的移動計算上。該演算法像Dijkstra演算法一樣,可以找到一條最短路徑;也像BFS一樣,進行啟發式的搜索。

㈦ 急求:初識A*演算法 這個的源代碼!!

#include <iostream>
#include <cmath>
using namespace std;

struct tnode{

int gvalue;//以下3個參數是估計函數
int hvalue;
int fvalue;
tnode* parent;//不是父節點,而是指向當前節點
tnode* next;//指向鏈表的下一個節點
int pass;
int nodevalue;//唯一標示節點
};

tnode table[5][5];//存儲地圖5*5
int startx,starty,endx,endy;
tnode openlist,closelist;

void computervalue(const int curx,const int cury);
int intsearch(tnode *plist,int value);//C++需要int
void addopenlist(int hx,int hy);
void handlenode(int hx,int hy,int curx,int cury);

void main()
{
tnode *pp;
int x,y;
int i,j;//要定義
for ( i=0;i<=4;i++)//初始化
for ( j=0;j<=4;j++)
{
table[i][j].gvalue=0;
table[i][j].hvalue=0;
table[i][j].fvalue=0;
table[i][j].parent=0;
table[i][j].next=0;
table[i][j].pass=1;
table[i][j].nodevalue=(i+1)*(j+1);
}
cout<<"輸入不可以通過的位置,格式為坐標X 坐標Y"<<endl;
for (i=1;i<=3;i++)
{
cin>>x>>y;
table[x][y].pass=0;
}

cout<<"輸入起始的位置,格式為坐標X 坐標Y"<<endl;
cin>>startx>>starty;

cout<<"輸入結束的位置,格式為坐標X 坐標Y"<<endl;
cin>>endx>>endy;

for (i=0;i<=4;i++)//列印地圖結構
{
cout<<endl;
for (int k=0;k<=4;k++)
cout<<table[i][k].pass;
}

computervalue(startx,starty);

pp=&table[endx][endy];
while(pp->parent)
{
pp=pp->next;
cout<<pp->parent->nodevalue<<"=>";
}
system("pause");

}
//遍歷鏈表,判段是否在列表中,找到返回1,否則返回0

int search(tnode *plist,int value)
{
while( (value!=plist->nodevalue) && plist->next)
plist=plist->next;

if(plist==0)
return 0;
else
return 1;
}

//把table[hx][hy]加入openlist有序鏈表

void addopenlist(int hx,int hy)
{

tnode *plist,*qlist=0;
plist=openlist.next;

while((plist->next!=0) && plist->nodevalue<(hx+1)*(hy+1) )
{
qlist=plist;
plist=plist->next;
}
table[hx][hy].next=qlist->next;
qlist->next=&table[hx][hy];

}

void handlenode(int hx,int hy,int curx,int cury)
{//對每一個相鄰節點執行以下操作

/*1.如果該相鄰節點不可通行或者該相鄰節點已經在封閉列表中,
則什麼操作也不執行,繼續檢驗下一個節點;
2如果該相鄰節點不在開放列表中,
則將該節點添加到開放列表中, 並將該相鄰節點的父節點設為當前節點,
同時保存該相鄰節點的G和F值;
3.如果該相鄰節點在開放列表中,
則判斷若經由當前節點到達該相鄰節點的G值是否小於原來保存的G值,
若小於,則將該相鄰節點的父節點設為當前節點,並重新設置該相鄰節點的G和F值.
*/

if(!search(&openlist,(hx+1)*(hy+1)) && table[hx][hy].pass!=0)
{//不在openlist中

addopenlist(hx,hy);
table[hx][hy].parent=&table[curx][cury];

if(abs(curx-hx)+abs(cury-hy)==2)//計算gvalue值,因為傳過來的hx,hy已經做過處理,這里只是處理+1,+2
table[hx][hy].gvalue+=2;
else table[hx][hy].gvalue+=1;

table[hx][hy].hvalue=(curx-hx)+(cury-hy);//計算hvalue
table[hx][hy].fvalue=table[hx][hy].gvalue+table[hx][hy].hvalue;//計算fvalue

}

else if(search(&openlist,(hx+1)*(hy+1)) && table[hx][hy].pass!=0)
{ //在openlist中
int tempx;//存放比較的中間值
if(abs(curx-hx)+abs(cury-hy)==2)
tempx=table[hx][hy].gvalue+2;
else tempx=table[hx][hy].gvalue+1;

if(tempx<table[hx][hy].gvalue)//判斷是否更新
table[hx][hy].gvalue=tempx;

table[hx][hy].hvalue=(curx-hx)+(cury-hy);//計算hvalue

table[hx][hy].fvalue=table[hx][hy].gvalue+table[hx][hy].hvalue;//更新fvalue

}

}

void computervalue(int curx,int cury)
{//對每一個當前節點執行以下操作

if(curx==0)
{
if(cury==0)
{
handlenode(curx,cury+1,curx,cury);

handlenode(curx+1,cury,curx,cury);

handlenode(curx+1,cury+1,curx,cury);

}
else if(cury==4)
{
handlenode(curx-1,cury,curx,cury);

handlenode(curx,cury-1,curx,cury);

handlenode(curx-1,cury-1,curx,cury);

}
else
{
handlenode(curx,cury-1,curx,cury);

handlenode(curx,cury+1,curx,cury);

handlenode(curx+1,cury-1,curx,cury);

handlenode(curx+1,cury,curx,cury);

handlenode(curx+1,cury+1,curx,cury);

}
}

else if(curx==4)
{
if(cury==0)
{
handlenode(curx-1,cury,curx,cury);
//table[curx-1][cury].gvalue+=1;
handlenode(curx,cury+1,curx,cury);

handlenode(curx-1,cury+1,curx,cury);
}

else if(cury==4)
{
handlenode(curx-1,cury-1,curx,cury);

handlenode(curx-1,cury,curx,cury);

handlenode(curx,cury-1,curx,cury);

}
else
{
handlenode(curx,cury-1,curx,cury);

handlenode(curx,cury+1,curx,cury);

handlenode(curx-1,cury-1,curx,cury);

handlenode(curx-1,cury,curx,cury);

handlenode(curx-1,cury+1,curx,cury);

}
}

else if(cury==0)
{
handlenode(curx-1,cury,curx,cury);

handlenode(curx+1,cury,curx,cury);

handlenode(curx-1,cury+1,curx,cury);

handlenode(curx,cury+1,curx,cury);

handlenode(curx+1,cury+1,curx,cury);

}

else if(cury==4)
{
handlenode(curx-1,cury-1,curx,cury);

handlenode(curx,cury-1,curx,cury);

handlenode(curx+1,cury-1,curx,cury);

handlenode(curx-1,cury,curx,cury);

handlenode(curx+1,cury,curx,cury);

}

else
{
handlenode(curx,cury+1,curx,cury);

handlenode(curx+1,cury,curx,cury);

handlenode(curx+1,cury+1,curx,cury);

handlenode(curx-1,cury,curx,cury);

handlenode(curx-1,cury-1,curx,cury);

handlenode(curx-1,cury+1,curx,cury);

handlenode(curx,cury-1,curx,cury);

handlenode(curx+1,cury-1,curx,cury);
}
}

㈧ 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);}

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

A演算法一般指某個搜索演算法的樸素的思路
A*指使用了啟發式搜索之後的演算法,也就是運算速度會快很多,但不一定能保證最後得到最優解

㈩ 求A* 演算法C語言源程序

#include <string.h>
#include <stdio.h>
#include <malloc.h>
#include <time.h>
#define NULL 0

const int nmax = 200;
const int nend = 99; /*終點坐標的代表點*/
static char achar[10][10];
static int npayo = 0; /*0 表示空 1為非空*/
static int npayc = 0; /*0 表示空 1為非空*/
static int npay_x = 0; /*起點*/
static int npay_y = 0;
static int nend_x = 9; /*終點*/
static int nend_y = 9;
static int nnewpay_x;
static int nnewpay_y;
static int ndian = 101;
static int nh;
static long i = 10000000L;

struct Spaydian
{
int ng;
int nf; /*路徑評分*/
int nmy_x; /*自己位置*/
int nmy_y;
int nfatherx; /*父節點*/
int nfathery;
int nflag; /* 0 wei O; 1 wei @ */
};
static struct Spaydian spaydian[200];

/* open close list 表 */
typedef struct spaylist
{
int n_f;
int n_x;
int n_y;
int nfather_x;
int nfather_y;
struct spaylist *next;
};
static struct spaylist *open_list, *close_list;

static void smline();
static int sjudge(int nx,int ny,int i); /*判斷在第nx列ny行向第i個方向走是否可以,可以返回1否則返回0。
i=1表示向右,2表示向下,3表示向左,4表示向上*/
static void spath();
static void spayshow(int nxx,int nyy);
static int sifopen( int nx,int ny); /*判斷點是否在 open 表上*/
static int sifclose(int nx,int ny); /*判斷點是否在 close 表上*/
static int snewx(int nx,int i);
static int snewy(int ny,int i);
static spaylist *creat(); /*建立鏈表*/
static spaylist *del(spaylist *head,int num_x,int num_y); /*刪除鏈表的結點*/
static spaylist *snewdianx(spaylist *head);/*新的點*/
static spaylist *snewdiany(spaylist *head);
static spaylist *insert(spaylist *head,int ndian); /* 點插入鏈表 */
static spaylist *srebirth(spaylist *head,int ndian); /*更新表*/

int main()
{
FILE *fp ;
char ach ;
int ni = 0 ; /*統計個數*/
int nii = 0; /*achar[nii][njj]*/
int njj = 0;
if ((fp=fopen("route.txt","rt")) == NULL) /* 判斷打開文件是否為空 */
{
printf("文件為空!~\n");
return 0;
/* exit(1);*/
}
ach = fgetc(fp);
while(ach != EOF)
{
if(ach == 'O' || ach == '@') /*當值為@或O時候*/
{
spaydian[ni].ng = 0;
spaydian[ni].nf = nmax;
spaydian[ni].nmy_x = njj;
spaydian[ni].nmy_y = nii;
spaydian[ni].nfathery = -1;
spaydian[ni].nfatherx = -1;
if(ach == '@')
{
spaydian[ni].nflag = 1;
}
else if(ach == 'O')
{
spaydian[ni].nflag = 0;
}
ni++;
achar[nii][njj] = ach;
njj++;
if(njj == 10)
{
nii++;
njj = 0;
}
} /*end if*/
ach = fgetc(fp);
}/*end while*/
smline(); /* a*演算法 */
fp=fopen("answer.txt","w");
for(int i=0;i<10;i++ )
{ for(int j=0;j<10;j++ )
{
printf("%c",achar[i][j]);
if(j==9)
printf("\n");
fprintf(fp,"%c",achar[i][j]);
if (j==9)
fprintf(fp,"\n");
}
}
fclose(fp);
return 0;
}

/* a* 演算法 */
static void smline()
{ close_list = open_list = NULL;
open_list = creat();
while(open_list != NULL) /* 當open 表不為空時 */
{
open_list = del(open_list,npay_x,npay_y); /*刪除open 鏈表的結點*/
if(npay_x == 9 && npay_y == 9)
{

achar[9][9] = '=';
spath(); /*尋找並畫出路徑*/
break;
}
for (int i=1; i<=4; i++) /*四個方向逐個行走,i=1向右 2向下 3向左 4向上*/
{
if (sjudge(npay_x,npay_y,i))
{

nnewpay_x = snewx(npay_x,i);
nnewpay_y = snewy(npay_y,i);
if(open_list != NULL)
npayo = sifopen(nnewpay_x,nnewpay_y) ; /*判斷點是否在 open 表中*/
else
npayo = 0;

if(close_list != NULL)
npayc = sifclose(nnewpay_x,nnewpay_y) ; /*判斷點是否在 close 表中*/
else
npayc = 0;
ndian = 10*nnewpay_x+nnewpay_y ;

if (npayo == 0 && npayc == 0 ) /*點不在open表也不在close表中*/
{
spaydian[ndian].ng = spaydian[10*npay_x+npay_y].ng + 1; /*更新點的基本信息*/
nh = (nend - ndian)/10 + (nend - ndian)%10 ;
spaydian[ndian].nf = spaydian[ndian].ng+nh;
spaydian[ndian].nfathery = npay_y;
spaydian[ndian].nfatherx = npay_x;
spaydian[ndian].nmy_y = nnewpay_y;
spaydian[ndian].nmy_x = nnewpay_x;

open_list = insert(open_list,ndian);/*點插入open 表中*/
}
else if (npayo == 1) /*點在open表中*/
{
spaydian[ndian].ng = spaydian[10*npay_x+npay_y].ng + 1;
nh = (nend - ndian)/10 + (nend - ndian)%10 ;
if(spaydian[ndian].nf > (spaydian[ndian].ng+nh) && spaydian[ndian].nf != nmax)
{
spaydian[ndian].nf = spaydian[ndian].ng+nh;
open_list = srebirth(open_list,ndian); /*點插入open 表中*/
}
}
else if(npayc == 1) /*新生成的點在close表中*/
{
spaydian[ndian].ng = spaydian[10*npay_x+npay_y].ng + 1;
nh = (nend - ndian)/10 + (nend - ndian)%10 ;
if(spaydian[ndian].nf > (spaydian[ndian].ng+nh) && spaydian[ndian].nf != nmax)
{
spaydian[ndian].nf = spaydian[ndian].ng+nh;
close_list = srebirth(close_list,ndian);
close_list = del(close_list,nnewpay_x,nnewpay_y); /*刪除close鏈表的結點*/
open_list = insert(open_list,ndian);/*點插入open 表中*/
}
}/*end else if*/
}/*end if*/
}/*end for*/
close_list = insert(close_list,(10*npay_x+npay_y));/*點插入close 表中*/
if(open_list != NULL)
{
npay_x = open_list->n_x;
npay_y = open_list->n_y;
}

}/*end while*/
if(open_list == NULL)
{printf("無路可走 \n");}
}

/*建立鏈表*/
spaylist *creat(void)
{
spaylist *head;
spaylist *p1;
int n=0;
p1=(spaylist*)malloc(sizeof(spaylist));
p1->n_f = 18;
p1->n_x = 0;
p1->n_y = 0;
p1->nfather_x = -1;
p1->nfather_x = -1;
p1->next = NULL;
head = NULL;
head=p1;
return(head);
}

/*刪除結點*/
spaylist *del(spaylist *head,int num_x,int num_y)
{
spaylist *p1, *p2;
if(head == NULL)
{
printf("\nlist null!\n");
return (head);
}
p1 = head;
while((num_y != p1->n_y ||num_x != p1->n_x )&& p1->next != NULL)
{
p2=p1;
p1=p1->next;
}
if(num_x == p1->n_x && num_y == p1->n_y )
{
if(p1==head)
head=p1->next;
else
p2->next=p1->next;
}

return (head);
}

/*輸出*/
static void spath()
{
int nxx;
int nyy;
nxx = spaydian[nend].nfatherx;
nyy = spaydian[nend].nfathery;

spayshow(nxx,nyy) ;
}

/*遞歸*/
void spayshow(int nxx,int nyy)
{ achar[nxx][nyy] = '=';
if( nxx != 0 || nyy != 0 )
{
int nxxyy = 10*nxx+nyy;
nxx = spaydian[nxxyy].nfatherx;
nyy = spaydian[nxxyy].nfathery;
spayshow(nxx,nyy);
}
}

/* 判斷周圍四個點是否可行 */
static int sjudge(int nx,int ny,int i)
{
if (i==1) /*判斷向右可否行走*/
{
if (achar[nx][ny+1]=='O' && ny<9)
{
return 1;
}
else
return 0;
}
else if (i==2) /*判斷向下可否行走*/
{
if (achar[nx+1][ny]=='O' && nx<9)
{
return 1;
}
else
return 0;
}
else if (i==3)/*判斷向左可否行走 */
{
if (ny > 0&&achar[nx][ny-1]=='O')
{
return 1;
}
else
return 0;
}
else if (i==4)/*判斷向上可否行走 */
{
if (nx > 0&&achar[nx-1][ny]=='O')
{
return 1;
}
else
return 0;
}
else
return 0;
}

/* 求新的x點 */
static int snewx(int nx,int i)
{
if(i == 1)
nx = nx;
else if(i == 2)
nx = nx+1;
else if(i == 3)
nx = nx;
else if(i == 4)
nx = nx-1;
return nx;
}
/* 求新的y點 */
static int snewy(int ny, int i)
{
if(i == 1)
ny = ny+1;
else if(i == 2)
ny = ny;
else if(i == 3)
ny = ny-1;
else if(i == 4)
ny = ny;
return ny;
}

/*判定點是否在open表中*/
int sifopen(int nx,int ny)
{
spaylist *p1, *p2;
p1 = open_list;
while((ny != p1->n_y || nx != p1->n_x )&& p1->next != NULL)
{
p2 = p1;
p1 = p1->next;
}
if(nx == p1->n_x && ny == p1->n_y)
return 1;
else
return 0;
}

/*判定點是否在close表中*/
int sifclose(int nx,int ny)
{

spaylist *p1, *p2;
p1 = close_list;
while((ny != p1->n_y ||nx != p1->n_x )&& p1->next != NULL)
{
p2=p1;
p1=p1->next;
}
if(nx == p1->n_x && ny == p1->n_y)
return 1;
else
return 0;
}

/*插入結點*/
spaylist * insert(spaylist *head,int ndian)
{
spaylist *p0,*p1,*p2;
p1=head;
p0=(spaylist*)malloc(sizeof(spaylist));
p0->n_f = spaydian[ndian].nf;
p0->n_x = spaydian[ndian].nmy_x;
p0->n_y = spaydian[ndian].nmy_y;
p0->nfather_x = spaydian[ndian].nfatherx;
p0->nfather_x = spaydian[ndian].nfathery;
p0->next = NULL;
if(head==NULL)
{
head=p0;
p0->next=NULL;
}
else
{
while((p0->n_f > p1->n_f)&&(p1->next!=NULL))
{
p2=p1;
p1=p1->next;
}
if(p0->n_f <= p1->n_f)
{
if(head==p1)
head=p0;
else
p2->next=p0;
p0->next=p1;
}
else
{
p1->next=p0;
p0->next=NULL;
}
}
return (head);
}

/* 更新鏈表 */
spaylist * srebirth(spaylist *head,int ndian)
{
spaylist *p1, *p2;
p1=head;
while(spaydian[ndian].nmy_x!=p1->n_x&&spaydian[ndian].nmy_x!=p1->n_x&&p1->next!=NULL)
{
p2=p1;
p1=p1->next;
}
if(spaydian[ndian].nmy_x==p1->n_x&&spaydian[ndian].nmy_x==p1->n_x)
{
p1->n_f = spaydian[ndian].nf;
}
return (head);
}

閱讀全文

與a演算法demo相關的資料

熱點內容
java編程最難的框架 瀏覽:754
linuxutils 瀏覽:172
android表情亂碼 瀏覽:750
播放窗口編程 瀏覽:612
編程和cpu 瀏覽:364
職業病時間怎麼演算法 瀏覽:991
多圖片合成pdf文檔 瀏覽:138
判斷網路命令 瀏覽:452
erp加密鎖聯系方式 瀏覽:20
英菲克怎麼配置桌面伺服器 瀏覽:990
什麼字體是英文可編譯 瀏覽:393
劍三為什麼關不掉伺服器同步 瀏覽:974
安卓怎麼玩蘋果伺服器地址 瀏覽:631
編譯原理與實驗教程答案 瀏覽:230
程序員請假被開除電影 瀏覽:119
安卓怎麼開啟鎖屏許可權 瀏覽:705
編譯器後端密碼 瀏覽:913
androidsetwallpaper 瀏覽:996
linux伺服器性能測試 瀏覽:170
android代碼設置layout 瀏覽:140