A*初步实现

来源:互联网 发布:淘宝网 pong ipad 编辑:程序博客网 时间:2024/06/05 06:25

       由前几天写的ACM代码改了下,昨天下午写的但再存储最短路径时有点问题,刚把最短路径存储改好了.加了个4方向还是8方向,在障碍物边上是否拐角绕行.这里面和<A*寻路初探>中有些区别,没对新扩展节点在OPENLIST中时做重新指向处理.道路不计成本.

  1. //A* 障碍拐角 4方向8方向
  2. #include <iostream>
  3. #include <list>
  4. #include <vector>
  5. #include <algorithm>
  6. using namespace std;
  7. int R,C;//地图行列
  8. int sr,sc,dr,dc;//起点 终点
  9. int map[100][100];//0是障碍1是可行
  10. bool turnCorner=true;//是否绕过拐角
  11. bool eight=true;//4方向和8方向扩展
  12. struct Node 
  13. {
  14.     int f,g,h;
  15.     int r,c;
  16.     int parent;
  17. };
  18. vector<Node> openList;
  19. vector<Node> closeList;
  20. vector<Node> bestList;
  21. Node child;
  22. int ABS(int a,int b)
  23. {
  24.     return max(a,b)-min(a,b);
  25. }
  26. bool dayu(Node & l,Node & r)
  27. {
  28.     return l.f>r.f;
  29. }
  30. bool check(Node value)
  31. {
  32.     if (value.r==child.r&&value.c==child.c)
  33.     {
  34.         return true;
  35.     }
  36.     return false;
  37. }
  38. void Init(Node &start)
  39. {
  40.     if (!openList.empty())
  41.     {
  42.         openList.clear();
  43.     }
  44.     openList.push_back(start);
  45.     if (!closeList.empty())
  46.     {
  47.         closeList.clear();
  48.     }
  49. }
  50. void BestPath(Node &best)
  51. {
  52.     Node mudi=best;
  53.     if (!bestList.empty())
  54.     {
  55.         bestList.clear();
  56.     }
  57.     while (mudi.parent>-1)
  58.     {
  59.         bestList.push_back(mudi);
  60.         mudi=closeList[mudi.parent];
  61.     }
  62. }
  63. bool Reach(int r,int c)
  64. {
  65.     if (!map[r][c]||r<0||c<0||r>R||c>C)
  66.         return false;
  67.     return true;
  68. }
  69. void Generate(Node &node,int r,int c)
  70. {
  71.     //不再open和close中
  72.     child.r=r;
  73.     child.c=c;
  74.     vector<Node>::iterator posOP=find_if(openList.begin(),openList.end(),check);
  75.     vector<Node>::iterator posCL=find_if(closeList.begin(),closeList.end(),check);
  76.     if (posOP==openList.end()&&posCL==closeList.end())
  77.     {
  78.         child.parent=closeList.size()-1;
  79.         child.g=node.g+1;   //GetCost(r,c)+node.g;
  80.         child.h=ABS(dr,r)+ABS(dc,c);    //(tr-r)*(tr-r)+(tc-c)*(tc-c)
  81.         child.f=child.g+child.h;
  82.         openList.push_back(child);
  83.         sort(openList.begin(),openList.end(),dayu);//openList.sort(dayu);
  84.     }
  85. }
  86. void kuozhan(Node &node)
  87. {
  88.     bool flag[4]={true};
  89.     if (Reach(node.r-1,node.c))// 上 
  90.     {
  91.         Generate(node,node.r-1,node.c);
  92.     }
  93.     else 
  94.     {flag[0]=false,flag[1]=false;}
  95.     if (Reach(node.r,node.c+1))//右
  96.     {
  97.         Generate(node,node.r,node.c+1);
  98.     }
  99.     else 
  100.     {flag[1]=false,flag[2]=false;}
  101.     if (Reach(node.r+1,node.c))// 下
  102.     {
  103.         Generate(node,node.r+1,node.c);
  104.     }
  105.     else 
  106.     {flag[2]=false,flag[3]=false;}
  107.     if (Reach(node.r,node.c-1))// 左 
  108.     {
  109.         Generate(node,node.r,node.c-1);
  110.     }
  111.     else 
  112.     {flag[3]=false,flag[0]=false;}
  113.     if (!eight)
  114.     {
  115.         return;
  116.     }
  117.     if (!turnCorner)
  118.     {
  119.         for(int i=0;i<4;i++)
  120.             flag[i]=true;
  121.     }
  122.     if (flag[0]&&Reach(node.r-1,node.c-1))// 左上 
  123.     {
  124.         Generate(node,node.r-1,node.c-1);
  125.     }
  126.     if (flag[1]&&Reach(node.r-1,node.c+1))//右上
  127.     {
  128.         Generate(node,node.r-1,node.c+1);
  129.     }
  130.     if (flag[2]&&Reach(node.r+1,node.c+1))// 右下
  131.     {
  132.         Generate(node,node.r+1,node.c+1);
  133.     }
  134.     if (flag[3]&&Reach(node.r+1,node.c-1))// 左下 
  135.     {
  136.         Generate(node,node.r+1,node.c-1);
  137.     }
  138. }
  139. void FindPath(int sr,int sc,int dr,int dc)
  140. {
  141.     Node temp,best;
  142.     temp.r=sr;
  143.     temp.c=sc;
  144.     temp.g=0;
  145.     temp.h=ABS(sr,dr)+ABS(sc,dc);
  146.     temp.f=temp.g+temp.h;
  147.     temp.parent=-1;
  148.     Init(temp);
  149.     while (!openList.empty())
  150.     {
  151.         closeList.push_back(openList.back());
  152.         openList.pop_back();
  153.         best=closeList.back();
  154.         if (best.r==dr&&best.c==dc)//找到
  155.         {
  156.             BestPath(best);
  157.             cout<<best.f<<endl;
  158.             return;
  159.         }
  160.         kuozhan(best);
  161.     }
  162.     //没路径
  163.     cout<<"NO WAY!/n";
  164. }
  165. void ShowPath()
  166. {
  167.     int i,j;
  168.     for (i=bestList.size();i>0;i--)
  169.     {
  170.         map[bestList.back().r][bestList.back().c]=8;
  171.         bestList.pop_back();
  172.     }
  173.     for (i=0;i<R;i++)
  174.     {
  175.         for (j=0;j<C;j++)
  176.         {
  177.             cout<<map[i][j]<<" ";
  178.         }
  179.         cout<<endl;
  180.     }
  181. }
  182. int main()
  183. {
  184.     freopen("in.txt","r",stdin);
  185.     int i,j;
  186.     cin>>R>>C;
  187.     for (i=0;i<R;i++)
  188.     {
  189.         for (j=0;j<C;j++)
  190.             cin>>map[i][j];
  191.     }
  192.     cin>>sr>>sc>>dr>>dc;
  193.     FindPath(sr,sc,dr,dc);
  194.     ShowPath();
  195.     return 0;
  196. }
  197. 输入:
  198. 10 10
    1 1 1 1 1 0 0 0 0 0
    1 2 0 0 1 1 1 1 1 0
    1 1 1 0 1 0 0 0 1 1
    0 0 1 0 1 1 1 0 1 1
    1 1 1 0 0 0 0 1 1 1
    1 1 0 0 1 1 1 1 1 1
    1 1 1 0 1 1 1 0 0 0
    0 0 1 0 0 0 2 0 1 1
    1 1 1 1 1 0 0 0 1 1
    1 1 1 1 1 1 1 1 1 1
    1 1 7 6
  199. 输出:
  200. 17
    1 8 8 8 8 0 0 0 0 0
    1 2 0 0 8 8 8 8 8 0
    1 1 1 0 1 0 0 0 8 1
    0 0 1 0 1 1 1 0 8 1
    1 1 1 0 0 0 0 8 8 1
    1 1 0 0 1 1 8 8 1 1
    1 1 1 0 1 1 8 0 0 0
    0 0 1 0 0 0 8 0 1 1
    1 1 1 1 1 0 0 0 1 1
    1 1 1 1 1 1 1 1 1 1