1. 程式人生 > >四種尋路演算法計算步驟比較

四種尋路演算法計算步驟比較

四種演算法是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通過

  1. #include <iostream.h>
  2. #include <memory.h>
  3. #include <stdlib.h>
  4. #define SX 11 //寬
  5. #define SY 10 //長
  6. int dx[4]={0,0,-1,1}; //四種移動方向對x和y座標的影響
  7. int dy[4]={-1,1,0,0};
  8. /*char Block[SY][SX]= //障礙表
  9. {{ 1,1,1,1,1,1,1,1,1,1,1 },
  10. { 1,0,1,0,1,0,0,0,0,0,1 },
  11. { 1,0,1,0,0,0,1,0,1,1,1 },
  12. { 1,0,0,0,0,0,1,0,0,0,1 },
  13. { 1,0,0,1,0,0,1,0,0,1,1 },
  14. { 1,0,1,0,0,1,0,1,0,0,1 },
  15. { 1,0,0,0,0,0,0,0,1,0,1 },
  16. { 1,0,1,0,0,0,1,0,1,0,1 },
  17. { 1,0,0,1,0,0,1,0,0,0,1 },
  18. { 1,1,1,1,1,1,1,1,1,1,1 }};*/
  19. char Block[SY][SX]= //障礙表
  20. {{ 1,1,1,1,1,1,1,1,1,1,1 },
  21. { 1,0,1,0,1,0,0,0,0,0,1 },
  22. { 1,0,1,0,0,0,1,0,1,1,1 },
  23. { 1,0,0,0,1,0,1,0,0,0,1 },
  24. { 1,0,1,1,0,0,1,0,0,1,1 },
  25. { 1,0,1,0,1,1,0,1,0,0,1 },
  26. { 1,0,0,0,0,0,0,0,1,0,1 },
  27. { 1,0,1,0,1,0,1,0,1,0,1 },
  28. { 1,0,0,1,0,0,1,0,1,0,1 },
  29. { 1,1,1,1,1,1,1,1,1,1,1 }};
  30. int MaxAct=4; //移動方向總數
  31. char Table[SY][SX]; //已到過標記
  32. int Level=-1; //第幾步
  33. int LevelComplete=0; //這一步的搜尋是否完成
  34. int AllComplete=0; //全部搜尋是否完成
  35. char Act[1000]; //每一步的移動方向,搜尋1000步,夠了吧?
  36. int x=1,y=1; //現在的x和y座標
  37. int TargetX=9,TargetY=8; //目標x和y座標
  38. int sum1=0,sum2=0;
  39. void Test( );
  40. void Back( );
  41. int ActOK( );
  42. int GetNextAct( );
  43. void main( )
  44. {
  45.     memset(Act,0,sizeof(Act)); //清零
  46.     memset(Table,0,sizeof(Table));
  47.     Table[y][x]=1; //做已到過標記
  48.     while (!AllComplete) //是否全部搜尋完
  49.     {
  50.         Level++;LevelComplete=0; //搜尋下一步
  51.         while (!LevelComplete)
  52.         {
  53.             Act[Level]=GetNextAct( ); //改變移動方向
  54.             if (Act[Level]<=MaxAct)
  55.                 sum1++;
  56.             if (ActOK( )) //移動方向是否合理
  57.             {
  58.                 sum2++;
  59.                 Test( ); //測試是否已到目標
  60.                 LevelComplete=1; //該步搜尋完成
  61.             }
  62.             else
  63.             {
  64.                 if (Act[Level]>MaxAct) //已搜尋完所有方向
  65.                     Back( ); //回上一步
  66.                 if (Level<0) //全部搜尋完仍無結果
  67.                     LevelComplete=AllComplete=1; //退出
  68.             }
  69.         }
  70.     }
  71. }
  72. void Test( )
  73. {
  74.     if ((x==TargetX)&&(y==TargetY)) //已到目標
  75.     {
  76.         for (int i=0;i<=Level;i++)
  77.             cout<<(int)Act; //輸出結果
  78.         cout<<endl;
  79.         cout<<Level+1<<" "<<sum1<<" "<<sum2<<endl;
  80.         LevelComplete=AllComplete=1; //完成搜尋
  81.     }
  82. }
  83. int ActOK( )
  84. {
  85.     int tx=x+dx[Act[Level]-1]; //將到點的x座標
  86.     int ty=y+dy[Act[Level]-1]; //將到點的y座標
  87.     if (Act[Level]>MaxAct) //方向錯誤?
  88.         return 0;
  89.     if ((tx>=SX)||(tx<0)) //x座標出界?
  90.         return 0;
  91.     if ((ty>=SY)||(ty<0)) //y座標出界?
  92.         return 0;
  93.     if (Table[ty][tx]==1) //已到過?
  94.         return 0;
  95.     if (Block[ty][tx]==1) //有障礙?
  96.         return 0;
  97.     x=tx;
  98.     y=ty; //移動
  99.     Table[y][x]=1; //做已到過標記
  100.     return 1;
  101. }
  102. void Back( )
  103. {
  104.     x-=dx[Act[Level-1]-1];
  105.     y-=dy[Act[Level-1]-1]; //退回原來的點
  106.     Table[y][x]=0; //清除已到過標記
  107.     Act[Level]=0; //清除方向
  108.     Level--; //回上一層
  109. }
  110. int GetNextAct( ) //找到下一個移動方向。這一段程式有些亂,
  111. //仔細看!
  112. {
  113.     int dis[4];
  114.     int order[4];
  115.     int t=32767;
  116.     int tt=2;
  117.     for (int i=0;i<4;i++)
  118.     dis=abs(x+dx-TargetX)+abs(y+dy-TargetY);
  119.     for (i=0;i<4;i++)
  120.     if (dis<t)
  121.     {
  122.         order[0]=i+1;
  123.         t=dis;
  124.     }
  125.     if (Act[Level]==0)
  126.         return order[0];
  127.     order[1]=-1;
  128.     for (i=0;i<4;i++)
  129.     if ((dis==t)&&(i!=(order[0]-1)))
  130.     {
  131.         order[1]=i+1;
  132.         break;
  133.     }
  134.     if (order[1]!=-1)
  135.     {
  136.         for (i=0;i<4;i++)
  137.             if (dis!=t)
  138.             {
  139.                 order[tt]=i+1;
  140.                 tt++;
  141.             }
  142.     }
  143.     else
  144.     {
  145.         for (i=0;i<4;i++)
  146.         if (dis!=t)
  147.         {
  148.             order[tt-1]=i+1;
  149.             tt++;
  150.         }
  151.     }
  152.     if (Act[Level]==order[0])
  153.         return order[1];
  154.     if (Act[Level]==order[1])
  155.         return order[2];
  156.     if (Act[Level]==order[2])
  157.         return order[3];
  158.     if (Act[Level]==order[3])
  159.         return 5;
  160. }