[C++]:A*——A Star算法简介
来源:互联网 发布:mysql数据库存储过程 编辑:程序博客网 时间:2024/06/10 13:45
A*算法 求最优解
来源于我的博客
算法一直维护两个表: Open和Close
将起点S加入Open中
将所有S可到达的点(障碍物以及位于Close表中的点均看成不可达)加入到Open中。将起点从Open中删去,并加入到Close中
①从Open中删去F值最小的点Min,并将其加入到Close中
②将Min点所有可到达的点加入Open中,并设这些点的父节点为Min。若某点已经在Open中,则比较其F值,若新路径F值较小,说明从Min走路更短,更新其父节点为Min;否则不更新此点
循环①②,直到Open中出现目的点E
公式表示为: f(n)=g(n)+h(n),
其中 f(n) 是从初始状态经由状态n到目标状态的代价估计,
g(n) 是在状态空间中从初始状态到状态n的实际代价,
h(n) 是从状态n到目标状态的最佳路径的估计代价。
通俗一点讲:
g(n)代表你从起始点到下一点的实际距离(制定到下一点的距离的规则)
h(n)是自己设计的函数,可以是到目的地大致的距离
可将循环过程封装成函数:
while (isNotEnd()) { Find_deleteMinFromOpen_AddToClose(); putReachableIntoOpen(close.back()); }
举个栗子:
对于以下图:5行15列
000000000000000
0000000x0000000
00s0000x0000e00
0000000x0000000
000000000000000
其中x为墙壁,s为起点,e为终点,建立合适的模型,调用A star算法,找到一条s到e的最短路径。
取直走G值为10,斜走G值为14
这里H值设定为无视障碍到达终点所需的 步数*10
我们看开始的几步:
000000000000000
0000000x0000000
00s0000x0000e00
0000000x0000000
000000000000000
灰色的点G=10,H=9*10 ,其F值最小,加入Close
000000000000000
0000000x0000000
00s0000x0000e00
0000000x0000000
000000000000000
灰色的点G=10+10,H=8*10 ,其F值最小,加入Close
000000000000000
0000000x0000000
00s0000x0000e00
0000000x0000000
000000000000000
灰色的点G=10+10+10,H=7*10 ,其F值最小,加入Close
000000000000000
0000000x0000000
00s0000x0000e00
0000000x0000000
000000000000000
灰色的点G=10+10+10+10,H=6*10 ,其F值最小,加入Close
以此循环,直到e在Open中,此时只需要沿着父节点往回走就可以到达起点了,这条路就是当前情况下最优的解
结果:
000000000000000
0000000x0000000
00s0000x0000e00
0000000x0000000
000000000000000
C++实现:
#include#include#include#includeusing namespace std;char square[5][15] = {//待求数据 '0','0','0','0','0','0','0','0','0','0','0','0','0','0','0', '0','0','0','0','0','0','0','x','0','0','0','0','0','0','0', '0','0','s','0','0','0','0','x','0','0','0','0','e','0','0', '0','0','0','0','0','0','0','x','0','0','0','0','0','0','0', '0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'};class point {public: point(char s) { v = s; G = 0; H = 0; F = 0; } pair ParentPosi; pair posi; char v;//value int F; int G; int H; int UpdateF() { F = G + H; return F; } int UpdateH() { int x = posi.first - 2; int y = posi.second - 12; x *= 10; y *= 10; if (x < 0) { x = -x; } if (y < 0) { y = -y; } H = x + y; return H; } void setPosi(pair x) { posi = x; } void setParentPosi(pair x) { ParentPosi= x; } void setG(int g) { G = g; } void setH(int h) { H = h; } point &operator = (point &s) { (*this).v=(s).v; (*this).ParentPosi = s.ParentPosi; (*this).posi = s.posi; (*this).F = s.F; (*this).G = s.G; (*this).H = s.H; return *this; }};vector open;vector close;point squ[5][15] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,'x',0,0,0,0,0,0,0, 0,0,'s',0,0,0,0,'x',0,0,0,0,'e',0,0, 0,0,0,0,0,0,0,'x',0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};bool isInOpenList(pair s) { for (int i = 0;i<open.size();i++) { if (open[i].posi == s) { return true; } } return false;}bool isInCloseList(pair s) { for (int i = 0;i<close.size();i++) { if (close[i].posi == s) { return true; } } return false;}void putReachableIntoOpen(point min) { int x = min.posi.first; int y = min.posi.second; int direc[8][2] = { 0,1, 1,1, 1,0, 1,-1, 0,-1, -1,-1, -1,0, -1,1 }; for (int i = 0;i < 8;i++) { x = x + direc[i][0]; y = y + direc[i][1]; if (isInOpenList(make_pair(x, y))&&close.size()>0) { int tempi = 0; for (int i = 0;i < open.size();i++) { if (open[i].posi == make_pair(x, y)) { tempi = i; } } if (direc[i][0] * direc[i][1] != 0) {//斜向 int G_now = close.back().G + 14; if (G_now < open[tempi].G) { //G比较小就更新路径 open[tempi].ParentPosi = make_pair(x, y); squ[open[tempi].posi.first][open[tempi].posi.second].ParentPosi = make_pair(x, y); } } else { int G_now = close.back().G + 10; } continue; } //既不在关闭也不在开启列表中而且可到达 就将其加入开启列表 if ((!isInOpenList(make_pair(x, y))) && (!isInCloseList(make_pair(x,y)))&&x >= 0 && x < 5 && square[x][y] != 'x') { squ[x][y].setParentPosi(min.posi); open.push_back(squ[x][y]); if (direc[i][0] * direc[i][1] != 0) {//斜向 squ[x][y].setG(squ[x][y].G+14); } else { squ[x][y].setG(squ[x][y].G + 10); } //cout << "(" << squ[x][y].posi.first << "," << squ[x][y].posi.second << ")" << endl; } x = x - direc[i][0]; y = y - direc[i][1]; } //cout << "------------------------" << "(" << x << "," << y << "):" << "------------------------" << endl;}void Find_deleteMinFromOpen_AddToClose() { point min_= open[0]; int tempi = 0; for (int i = 0;i < open.size();i++) { if (open[i].UpdateF() < min_.UpdateF()) { min_ = open[i]; tempi = i; } } close.push_back(min_); std::vector::iterator it=open.begin()+tempi; open.erase(it); //cout << "close: (" << min_.posi.first << "," << min_.posi.second << ")" << endl; //cout << "closeSize()=" << close.size() << endl; //cout << "openSize()=" << open.size() << endl;}bool isNotEnd() { for (int i=0;i<open.size();i++) { if (open[i].v == 'e') { open[i].ParentPosi=close.back().posi; return false; } } return true;}void findPath(pair begin,pairend) { //将起点放入open open.push_back(squ[2][2]); putReachableIntoOpen(squ[2][2]); int tempi = 0; for (int i = 0;i < open.size();i++) { if (open[i].v == 's') { tempi = i; } } std::vector::iterator it = open.begin()+tempi;//删除起点 while (isNotEnd()) { Find_deleteMinFromOpen_AddToClose(); putReachableIntoOpen(close.back()); }}void print_path() { for (int i = 0;i < 5;i++) { for (int j = 0;j < 15;j++) { squ[i][j].posi = make_pair(i, j); squ[i][j].UpdateH();//算出所有H } }//初始化point.posi findPath(make_pair(2,2),make_pair(2,12)); point temp = squ[2][12]; vector<pair> point_out; while (temp.posi!=squ[2][2].posi) { //cout << "(" << temp.posi.first << "," << temp.posi.second << ")" << endl; point_out.push_back(temp.posi); temp=squ[temp.ParentPosi.first][temp.ParentPosi.second]; } point_out.push_back(squ[2][2].posi); while (point_out.size() != 0) { cout << "(" << point_out.back().first<< "," << point_out.back().second<< ")" << endl; point_out.pop_back(); }}void print() { for (int i = 0;i < 5;i++) { for (int j = 0;j < 15;j++) { cout << square[i][j] << ' '; } cout << endl; }}int main() { //print(); print_path(); return 0;}
- [C++]:A*——A Star算法简介
- [C++]:A*——A Star算法简介
- 算法——A-star算法
- A-Star(A*)算法
- A-Star 算法
- a-star算法
- 【算法】A star algorithm
- A-star算法
- A-STAR算法说明
- A Star算法
- A star算法
- 关于A*(A-star)算法
- A*(A Star)算法
- A星(A*, A Star)算法详解
- A星(A*, A Star)算法详解
- A星(A*, A Star)算法详解
- A星(A*, A Star)算法详解
- A星(A*, A Star)算法详解
- PHP无法上传大文件解决办法记录
- 【Ts 2】Nginx服务器搭建
- 修改查看MYSQL字符集(charset)
- 进度条ProcessBar示例
- 012-cmp指令与JZ指令
- [C++]:A*——A Star算法简介
- 小白日记11:kali渗透测试之服务扫描-banner、dmitry、nmap特征库、操作系统识别、SNMP
- 百度SDK公交路线
- linux的一些配置方法
- HDU2602-01背包基础
- Easyui 表单验证
- HDU1248-寒冰王座
- JS跳转页面的方法总结
- LeetCode 395 Longest Substring with At Least K Repeating Characters