• 三维地图中的A*寻路


    跟二维地图原理一样,只不过搜索方向多了,二维只搜8个方向,而三维要搜26个方向。

    不懂的看我以前写的文章,这里直接贴代码:

    #include <iostream>
    #include <cstring>
    #include <algorithm>
    #include <windows.h>
    #include <cmath>
    #include <list>
    #include <cstdio>
    
    using namespace std;
    
    const double LEN=10;
    const int MAX=500;
    const char ROAD='*';
    const char WALL='#';
    const char START='0';
    const char STOP='1';
    
    typedef struct node
    {
        node()
        {
            x=y=z=0;
            f=g=h=0;
            parent=NULL;
        }
        int x,y,z;
        double f,g,h;
        struct node *parent;
    } Node;
    
    char mmap[MAX][MAX][MAX];     //地图
    list<Node*> startList,stopList;  //开启列表和关闭列表
    
    int sx,sy,sz,ex,ey,ez;    //起点坐标(sx,sy,sz)和终点坐标(ex,ey,ez)
    int k,n,m;                //高度k,m行n列
    
    //26个方向,三阶魔方模型自己想象一下
    int dx[26]= {-1,1,0,0,-1,1,-1,1,0,-1,1,0,0,-1,1,-1,1,0,-1,1,0,0,-1,1,-1,1};
    int dy[26]= {0,0,-1,1,-1,-1,1,1,0,0,0,-1,1,-1,-1,1,1,0,0,0,-1,1,-1,-1,1,1};
    int dz[26]= {0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
    
    //计算两点距离
    double getDis(int x1,int y1,int z1,int x2,int y2,int z2)
    {
        double xx1=x1*LEN+LEN/2.0;   //获取中心点坐标
        double yy1=y1*LEN+LEN/2.0;
        double zz1=z1*LEN+LEN/2.0;
    
        double xx2=x2*LEN+LEN/2.0;
        double yy2=y2*LEN+LEN/2.0;
        double zz2=z2*LEN+LEN/2.0;
    
        return sqrt((xx1-xx2)*(xx1-xx2)+(yy1-yy2)*(yy1-yy2)+(zz1-zz2)*(zz1-zz2));
    }
    
    //判断节点是否在列表中
    bool in_List(Node *pnode,list<Node*> mlist)
    {
        for(list<Node*>::iterator it=mlist.begin(); it!=mlist.end(); it++)
        {
            if(pnode->x==(*it)->x&&pnode->y==(*it)->y&&pnode->z==(*it)->z)
                return true;
        }
        return false;
    }
    
    //从列表中删除节点
    bool del(Node *pnode,list<Node*> &mlist)
    {
        for(list<Node*>::iterator it=mlist.begin(); it!=mlist.end(); it++)
        {
            if(pnode==(*it))
            {
                mlist.erase(it);
                return true;
            }
        }
        return false;
    }
    
    //向列表中添加节点
    void add(Node *pnode,list<Node*> &mlist)
    {
        mlist.push_back(pnode);
        return;
    }
    
    //从列表中获取f最小的节点
    Node* getMin(list<Node*> mlist)
    {
        double mmin=100000000;
        Node *temp=NULL;
        for(list<Node*>::iterator it=mlist.begin(); it!=mlist.end(); it++)
        {
            if((*it)->f<mmin)
            {
                mmin=(*it)->f;
                temp=(*it);
            }
        }
        return temp;
    }
    
    //设置路径
    void setRoad(Node *root)
    {
        while(root->parent!=NULL)
        {
            if(root->x==ex&&root->y==ey&&root->z==ez)
            {
                mmap[root->z][root->x][root->y]=STOP;
            }
            else
                mmap[root->z][root->x][root->y]=ROAD;
            root=root->parent;
        }
    }
    
    void printRoad()
    {
        for(int kk=0; kk<k; kk++)
        {
            for(int i=0; i<m; i++)
            {
                for(int j=0; j<n; j++)
                {
                    if(mmap[kk][i][j]==ROAD||mmap[kk][i][j]==START||mmap[kk][i][j]==STOP)
                    {
                        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN);
                        cout<<mmap[kk][i][j]<<" ";
                    }
                    else
                    {
                        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY);
                        cout<<mmap[kk][i][j]<<" ";
                    }
                }
                cout<<endl;
            }
            cout<<endl<<endl;
        }
        cout<<endl<<endl<<endl;
        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY);
    }
    
    
    //搜索
    void bfs()
    {
        startList.clear();
        stopList.clear();
        Node *preNode = new Node;
        preNode->x=sx;
        preNode->y=sy;
        preNode->z=sz;
        preNode->g=0;
        preNode->h=getDis(sx,sy,sz,ex,ey,ez);
        preNode->f=preNode->g+preNode->h;
        preNode->parent=NULL;
        add(preNode,startList);
        while(!startList.empty())
        {
            //cout<<"-.-"<<endl;
            preNode=getMin(startList);
            if(preNode==NULL)
            {
                cout<<"自动寻路失败"<<endl;
                return;
            }
            del(preNode,startList);
            add(preNode,stopList);
            for(int d=0; d<26; d++)
            {
                int cx=preNode->x+dx[d];
                int cy=preNode->y+dy[d];
                int cz=preNode->z+dz[d];
    
                Node *curNode=new Node;
                curNode->x=cx;
                curNode->y=cy;
                curNode->z=cz;
                curNode->g=preNode->g+getDis(cx,cy,cz,preNode->x,preNode->y,preNode->z);
                curNode->h=getDis(cx,cy,cz,ex,ey,ez);
                curNode->f=curNode->g+curNode->h;
                curNode->parent=preNode;
    
                if(cx<0||cy<0||cz<0||cx>=m||cy>=n||cz>=k) continue;   //越界 或碰墙
                else if(mmap[cz][cx][cy]==WALL) continue;
                else if(in_List(curNode,startList)||in_List(curNode,stopList)) continue;  //在开启或关闭列表
    
                if(cx==ex&&cy==ey&&cz==ez)
                {
                    setRoad(curNode);
                    printRoad();
                    return;
                }
                add(curNode,startList);
            }
        }
        cout<<"自动寻路失败"<<endl;
        return;
    }
    
    int main()
    {
        while(cin>>k>>m>>n)
        {
            if(k==0||n==0||m==0) break;
            for(int kk=0; kk<k; kk++)
            {
                for(int i=0; i<m; i++)
                {
                    for(int j=0; j<n; j++)
                    {
                        cin>>mmap[kk][i][j];
                        if(mmap[kk][i][j]==START)
                        {
                            sx=i,sy=j,sz=kk;
                        }
                        if(mmap[kk][i][j]==STOP)
                        {
                            ex=i,ey=j,ez=kk;
                        }
                    }
                }
            }
            bfs();
            //printRoad();
    
        }
        return 0;
    }
    

      测试样例:

    3 10 8
    ````#```
    ``###```
    ``###```
    ``#`````
    ``#`##``
    ``#`#``#
    `##`#``#
    `###`##`
    `0##`##`
    ####`#``
    
    ````#```
    ``#`#```
    ``#`#```
    ``#`````
    ``#`##``
    ``#`#``#
    `##`#`##
    `###`##`
    ``##`##`
    ####`#``
    
    ````#```
    ``#`#```
    ``#`#```
    ``#`````
    ``#`##``
    ``#`#``#
    `##`#``#
    `###`##`
    ``#``##`
    ####`#`1

    输出结果:

    人生如修仙,岂是一日间。何时登临顶,上善若水前。
  • 相关阅读:
    记RestTemplate远程请求接口数据的一些注意事项
    记使用SpringDataMongonDb时,dao方法命名的一个已解决但不知道为什么的bug
    charles 打断点后传参或返回数据更改
    在liunx上搭建git仓库1
    jsonpath 提取参数
    pytest 参数化的使用1
    pytest中断言失败后,也可以继续执行其他用例
    charles开启弱网功能
    httprunner 参数化
    httprunner中debugtalk使用
  • 原文地址:https://www.cnblogs.com/f-society/p/6826738.html
Copyright © 2020-2023  润新知