四種尋路算法並比較

好久沒搞這些東西了...想了十分鐘才勉強回憶起來...
寫了三個鐘頭...好累啊...
四種算法是DFS,BFS,Heuristic DFS, Heuristic BFS (A*)
用了兩張障礙表,一張是典型的迷宮:

char Block[SY][SX]=
{{1,1,1,1,1,1,1,1,1,1,1 },
{1,0,1,0,1,0,0,0,0,0,1 },
{1,0,1,0,0,0,1,0,1,1,1 },
{1,0,0,0,1,0,1,0,0,0,1 },
{1,0,1,1,0,0,1,0,0,1,1 },
{1,0,1,0,1,1,0,1,0,0,1 },
{1,0,0,0,0,0,0,0,1,0,1 },
{1,0,1,0,1,0,1,0,1,0,1 },
{1,0,0,1,0,0,1,0,1,0,1 },
{1,1,1,1,1,1,1,1,1,1,1 }};

第二張是刪掉一些障礙後的:

char Block[SY][SX]=
{{1,1,1,1,1,1,1,1,1,1,1 },
{1,0,1,0,1,0,0,0,0,0,1 },
{1,0,1,0,0,0,1,0,1,1,1 },
{1,0,0,0,0,0,1,0,0,0,1 },
{1,0,0,1,0,0,1,0,0,1,1 },
{1,0,1,0,0,1,0,1,0,0,1 },
{1,0,0,0,0,0,0,0,1,0,1 },
{1,0,1,0,0,0,1,0,1,0,1 },
{1,0,0,1,0,0,1,0,0,0,1 },
{1,1,1,1,1,1,1,1,1,1,1 }};

結果:
嘗試節點數 合法節點數 步數
深度優先 416/133 110/43 19/25
廣度優先 190/188 48/49 19/15
深度+啓發 283/39 82/22 19/19
廣度+啓發 189/185 48/49 19/15

所以可以看出深度+啓發是最好的,效率高路徑也挺短。A*第一是不真實二是慢三是空間消耗較大。

附:dfs+heu的源程序,bc++ 3.1通過


#include <iostream.h>
#include <memory.h>
#include <stdlib.h>

#define SX 11 //寬
#define SY 10 //長

int dx[4]={0,0,-1,1}; //四種移動方向對x和y座標的影響
int dy[4]={-1,1,0,0};

/*char Block[SY][SX]= //障礙表
{{ 1,1,1,1,1,1,1,1,1,1,1 },
{ 1,0,1,0,1,0,0,0,0,0,1 },
{ 1,0,1,0,0,0,1,0,1,1,1 },
{ 1,0,0,0,0,0,1,0,0,0,1 },
{ 1,0,0,1,0,0,1,0,0,1,1 },
{ 1,0,1,0,0,1,0,1,0,0,1 },
{ 1,0,0,0,0,0,0,0,1,0,1 },
{ 1,0,1,0,0,0,1,0,1,0,1 },
{ 1,0,0,1,0,0,1,0,0,0,1 },
{ 1,1,1,1,1,1,1,1,1,1,1 }};*/

char Block[SY][SX]= //障礙表
{{ 1,1,1,1,1,1,1,1,1,1,1 },
{ 1,0,1,0,1,0,0,0,0,0,1 },
{ 1,0,1,0,0,0,1,0,1,1,1 },
{ 1,0,0,0,1,0,1,0,0,0,1 },
{ 1,0,1,1,0,0,1,0,0,1,1 },
{ 1,0,1,0,1,1,0,1,0,0,1 },
{ 1,0,0,0,0,0,0,0,1,0,1 },
{ 1,0,1,0,1,0,1,0,1,0,1 },
{ 1,0,0,1,0,0,1,0,1,0,1 },
{ 1,1,1,1,1,1,1,1,1,1,1 }};

int MaxAct=4; //移動方向總數
char Table[SY][SX]; //已到過標記
int Level=-1; //第幾步
int LevelComplete=0; //這一步的搜索是否完成
int AllComplete=0; //全部搜索是否完成
char Act[1000]; //每一步的移動方向,搜索1000步,夠了吧?
int x=1,y=1; //現在的x和y座標
int TargetX=9,TargetY=8; //目標x和y座標
int sum1=0,sum2=0;

void Test( );
void Back( );
int ActOK( );
int GetNextAct( );

void main( )
{
memset(Act,0,sizeof(Act)); //清零
memset(Table,0,sizeof(Table));
Table[y][x]=1; //做已到過標記
while (!AllComplete) //是否全部搜索完
{
Level++;LevelComplete=0; //搜索下一步
while (!LevelComplete)
{
Act[Level]=GetNextAct( ); //改變移動方向
if (Act[Level]<=MaxAct)
sum1++;
if (ActOK( )) //移動方向是否合理
{
sum2++;
Test( ); //測試是否已到目標
LevelComplete=1; //該步搜索完成
}
else
{
if (Act[Level]>MaxAct) //已搜索完所有方向
Back( ); //回上一步
if (Level<0) //全部搜索完仍無結果
LevelComplete=AllComplete=1; //退出
}
}
}
}

void Test( )
{
if ((x==TargetX)&&(y==TargetY)) //已到目標
{
for (int i=0;i<=Level;i++)
cout<<(int)Act[i]; //輸出結果
cout<<endl;
cout<<Level+1<<" "<<sum1<<" "<<sum2<<endl;
LevelComplete=AllComplete=1; //完成搜索
}
}

int ActOK( )
{
int tx=x+dx[Act[Level]-1]; //將到點的x座標
int ty=y+dy[Act[Level]-1]; //將到點的y座標
if (Act[Level]>MaxAct) //方向錯誤?
return 0;
if ((tx>=SX)||(tx<0)) //x座標出界?
return 0;
if ((ty>=SY)||(ty<0)) //y座標出界?
return 0;
if (Table[ty][tx]==1) //已到過?
return 0;
if (Block[ty][tx]==1) //有障礙?
return 0;
x=tx;
y=ty; //移動
Table[y][x]=1; //做已到過標記
return 1;
}

void Back( )
{
x-=dx[Act[Level-1]-1];
y-=dy[Act[Level-1]-1]; //退回原來的點
Table[y][x]=0; //清除已到過標記
Act[Level]=0; //清除方向
Level--; //回上一層
}

int GetNextAct( ) //找到下一個移動方向。這一段程序有些亂,
//仔細看!
{
int dis[4];
int order[4];
int t=32767;
int tt=2;
for (int i=0;i<4;i++)
dis[i]=abs(x+dx[i]-TargetX)+abs(y+dy[i]-TargetY);
for (i=0;i<4;i++)
if (dis[i]<t)
{
order[0]=i+1;
t=dis[i];
}
if (Act[Level]==0)
return order[0];
order[1]=-1;
for (i=0;i<4;i++)
if ((dis[i]==t)&&(i!=(order[0]-1)))
{
order[1]=i+1;
break;
}
if (order[1]!=-1)
{
for (i=0;i<4;i++)
if (dis[i]!=t)
{
order[tt]=i+1;
tt++;
}
}
else
{
for (i=0;i<4;i++)
if (dis[i]!=t)
{
order[tt-1]=i+1;
tt++;
}
}

if (Act[Level]==order[0])
return order[1];
if (Act[Level]==order[1])
return order[2];
if (Act[Level]==order[2])
return order[3];
if (Act[Level]==order[3])
return 5;
}

本文來自: 中國自學編程網(www.zxbc.cn) 詳細出處參考:http://www.zxbc.cn/html/yxkf/1409430749280.htm 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章