A*启发式搜索模板
来源:互联网 发布:ping怎么加端口号 编辑:程序博客网 时间:2024/05/19 17:23
博主本身很想提高一下自己的水平,于是打算写一下以前一直觉得很难的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*/
阅读全文
1 0
- A*启发式搜索 模板
- A*启发式搜索模板
- 启发式搜索技术 A*
- A*启发式搜索
- A*启发式搜索基础
- 启发式搜索A * 算法
- A*启发式搜索
- 启发式搜索技术A*
- 启发式搜索技术A*【译】
- hdu6181-启发式搜索A*|次短路模板|最短路枚举-Two Paths
- 启发式搜索A*算法 - [算法学习]
- 启发式搜索算法A*(2)
- 第k最短路A*启发式搜索
- 【启发式搜索】A*与IDA*学习笔记
- A*启发式搜索算法详解 人工智能
- 八数码问题-启发式搜索(A*算法)
- 第k短路 A*启发式搜索解决
- 启发式搜索算法(A*算法)
- 数据库第四章 数据库安全性
- 如何利用KMP的next求字符串的循环节
- redis 学习笔记一
- JavaScript
- cmd命令模式下总是要切换到管理员身份进行
- A*启发式搜索模板
- Android h5 交互
- c语言符号定义、声明、引用、作用域及生命期、优化
- climbStairs
- 总结11
- python3
- ORA-01031 权限不足
- 51nod1083之DP
- 设计模式-单例模式