四种寻路算法计算步骤比较

来源:互联网 发布:seo跟sem的区别 编辑:程序博客网 时间:2024/05/19 09:37

四种算法是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. }
0 0
原创粉丝点击