A*启发式搜索 模板

来源:互联网 发布:linux切换用户权限命令 编辑:程序博客网 时间:2024/05/22 14:05

博主本身很想提高一下自己的水平,于是打算写一下以前一直觉得很难的A*启发式搜索,努力工作了一个多小时,终于把这么一个恶心的程序调试完成了(不要问我启发式搜索是什么,网上有的是,博主只是给大家提供一下参考代码),这个代码都有注释,而且测试通过了(最末端有博主的测试数据之一),希望大家可以因此有所提高!

/*ID: ljf_cnyaliPROG: A*LANG: C++*/#include<bits/stdc++.h>using namespace std;#define REP(i, a, b) for(int i = (a), _end_ = (b);i <= _end_; ++ i)#define mem(a) memset((a), 0, sizeof(a))#define str(a) strlen(a)const int maxn = 1010;int Row, Col;//地图大小 struct block {    int f, g, h, Fx, Fy, Mx, My;//F = G + H, Fx, Fy是父亲的坐标, Mx, My是现在的坐标 };int dt[4][2] = {{0, -1}, {-1, 0}, {1, 0}, {0, 1}};//east, south, north, weststruct block Open[maxn], Close[maxn];//队列int Startx, Starty, Endx, Endy;//起点终点坐标int Map[maxn][maxn];//地图, 1代表墙 int CountOpen, CountClose;//队列坐标个数 void INIT() {    scanf("%d%d", &Row, &Col);    REP(i, 0, Row - 1)        REP(j, 0, Col - 1)            scanf("%d", &Map[i][j]);    scanf("%d%d%d%d", &Startx, &Starty, &Endx, &Endy);} int getG(int x, int y) {    return abs(x - Startx) + abs(y - Starty); } int getH(int x, int y) {    return abs(x - Endx) + abs(y - Endy);}void InOpen(int Fx, int Fy, int Mx, int My) {    Open[CountOpen].g = getG(Mx, My);    Open[CountOpen].h = getH(Mx, My);    Open[CountOpen].f = Open[CountOpen].g + Open[CountOpen].h;    Open[CountOpen].Fx = Fx;    Open[CountOpen].Fy = Fy;    Open[CountOpen].Mx = Mx;    Open[CountOpen].My = My;    ++CountOpen;        }void DeleteOpen(int index) {    REP(i, index, CountOpen - 1)        Open[i] = Open[i + 1];    --CountOpen;}void InClose(int index) {    Close[CountClose] = Open[index];    ++CountClose;       DeleteOpen(index);//将index从Open中删去 }void PrintfPath() {    int ans = 0;    //目的地的父亲坐标     int Fx = Close[CountClose - 1].Fx;    int Fy = Close[CountClose - 1].Fy;    //找目的地的父亲,向上推    for(int i = CountClose - 1;i >= 0; -- i)         if(Close[i].Mx == Fx && Close[i].My == Fy) {            printf("Result: %d, %d\n", Fx, Fy);            Fx = Close[i].Fx;            Fy = Close[i].Fy;            ++ans;        }    printf("%d\n", ans);//输出距离 }int SearchRound(int x, int y) {    bool flag;    REP(i, 0, 3) {        int dx = dt[i][0] + x;        int dy = dt[i][1] + y;        flag = true;        //即将进入Open里的检查:Close数组检查、Open数组检查、墙、能进Open        //Close或Open数组里已经包含了则不能进入        REP(j, 0, CountClose - 1)            if(dx == Close[j].Mx && dy == Close[j].My) {                flag = false;                break;            }        REP(j, 0, CountOpen - 1)            if(dx == Open[j].Mx && dy == Open[j].My) {                flag = false;                break;              }        if(Map[dx][dy] == 1)            flag = false;        //如果flag为真,则加入Open        if(flag)            InOpen(x, y, dx, dy);           //是否到达终点        if(dx == Endx && dy == Endy)            return 1;       }    return 0;}void ShorestPath() {    int x = Startx, y = Starty, k;    //设置起点    Open[CountOpen].g = getG(x, y);//查找G(x, y)的值     Open[CountOpen].h = getH(x, y);//查找H(x, y)的值    Open[CountOpen].f = Open[CountOpen].g + Open[CountOpen].h;//计算F(x, y)的值    Open[CountOpen].Fx = -1;    Open[CountOpen].Fy = -1;    Open[CountOpen].Mx = x;    Open[CountOpen].My = y;    ++CountOpen;//队列继续    //选出Open中F值最小的一个     while(1) {        int min = 1000000000, index = 0;        REP(i, 0, CountOpen - 1)             if(Open[i].f < min) {                min = Open[i].f;                index = i;            }        //把F最小的放入Close中         InClose(index);        int flag = SearchRound(Close[CountClose - 1].Mx, Close[CountClose - 1].My);//寻找可以走的路径         if(flag == 1) {            InClose(CountOpen - 1);//把终点放入Close中             PrintfPath();//输出路径,注意是从后往前输出的             break;          }    }}int main() {//  freopen("A*.in", "r", stdin);//  freopen("A*.out", "w", stdout);    INIT();//读入地图    ShorestPath();//主代码     return 0;}/*8 91 1 1 1 1 1 1 1 11 0 0 0 0 0 0 0 11 0 0 0 1 0 0 0 11 0 0 0 1 0 0 0 11 0 0 0 1 0 0 0 11 0 1 0 1 0 0 0 11 0 0 0 0 0 0 0 11 1 1 1 1 1 1 1 14 2 1 7*/
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 耳朵戳伤流血了怎么办 耳朵挖破出血了怎么办 耳朵让耳屎堵了怎么办 手被牙齿划破了怎么办 耳朵掏伤了很痛怎么办 掏伤耳朵发炎了怎么办 耳朵被掏发炎了怎么办 打的耳洞化脓了怎么办 打了耳洞流脓了怎么办 打了耳洞发炎怎么办 打了耳洞化脓了怎么办 3岁宝宝耳朵流脓怎么办 耳朵里面是湿的怎么办 耳朵里天天很痒怎么办 身上长湿疹很痒怎么办 嗓子干疼耳朵痒怎么办 上火了耳朵嗡嗡响怎么办 太阳凹颧骨外扩怎么办 4岁儿童脊柱侧弯怎么办 瘦的人得多囊怎么办 智齿刚长出来该怎么办 宝宝耳朵睡尖了怎么办 睡觉压的耳朵疼怎么办 月子里奶水越来越少怎么办 月子里生气回奶了怎么办 儿童疫苗本丢了怎么办 跖骨2-5骨折了怎么办 耳朵被水堵住了怎么办 耳朵一直流黄水怎么办 两个月宝宝脐疝怎么办 拔牙后一直渗血怎么办 耳朵滴药水堵了怎么办 刚打的耳洞化脓怎么办 耳朵进水了一直嗡嗡响怎么办 婴儿游泳呛水了怎么办 孩子游泳呛水了怎么办 婴儿洗澡呛水了怎么办 小孩脸上长湿疹老是不好怎么办 油耳堵住了耳朵怎么办 耳屎突然变湿该怎么办 小孩有耳屎好硬怎么办