poj 2243(A*搜索orBFS)
来源:互联网 发布:dijkstra算法优先队列 编辑:程序博客网 时间:2024/04/30 14:40
Knight Moves
以前听说过A*搜索这个推崇备至的算法,但没有去认真阅读过相关资料,今天(2013/10/0D)认真学习了一下
通过这题学习了A*搜索,下面就来描述一下A*搜索的详细过程:
1,把起始格添加到开启列表。2,重复如下的工作:
a) 寻找开启列表中F值最低的格子。我们称它为当前格。
b) 把它切换到关闭列表。
c) 对相邻的格中的每一个?
* 如果它不可通过或者已经在关闭列表中,略过它。反之如下。
* 如果它不在开启列表中,把它添加进去。把当前格作为这一格的父节点。记录这一格的F,G,和H值。
* 如果它已经在开启列表中,用G值为参考检查新的路径是否更好。更低的G值意味着更好的路径。如果是这样,就把这一格的父节点改成当前格,并且重新计算这一格的G和F值。如果你保持你的开启列表按F值排序,改变之后你可能需要重新对开启列表排序。
d) 停止,当你
* 把目标格添加进了关闭列表(注解),这时候路径被找到,或者
* 没有找到目标格,开启列表已经空了。这时候,路径不存在。
3.保存路径。从目标格开始,沿着每一格的父节点移动直到回到起始格。这就是你的路径。
下面就来做题巩固一下:
poj 2243 Knight Moves
题目的意思大概是说:在国际象棋的棋盘上,一匹马共有8个可能的跳跃方向,求从起点到目标点之间的最少跳跃次数。
内存:176K 耗时 : 32MS (将队列定义为全局,可减少时间)
#include <iostream>#include <cstdio>#include <cstring>#include <queue>#include <cmath>using namespace std;struct knight{ int x,y,step; int f,g,h;//启发:f=g+h; bool operator <(const knight& a)const{ return f>a.f;//重载<,每次选择代价最小的 } bool operator ==(const knight& a) { return (x==a.x&&y==a.y)?1:0; } bool ok() { if(x>=0&&x<8&&y>=0&&y<8) return 1; else return 0; }}s,e;bool vis[8][8];//已访问列表int dir[8][2]={{-2,-1},{-2,1},{-1,2},{1,2},{2,1},{2,-1},{1,-2},{-1,-2}};priority_queue<knight>Q;//定义为全局可减少时间int Heuristic(const knight& a){ //用曼哈顿距离作为估值函数 return (abs(a.x-e.x)+abs(a.y-e.y))*10;//距离扩大10倍}int Astar(){ memset(vis,0,sizeof(vis)); while(!Q.empty()) Q.pop(); Q.push(s); vis[s.x][s.y]=1; if(s==e)return 0; knight pre,now; while(!Q.empty()) { pre=Q.top(); Q.pop(); for(int i=0;i<8;i++) { now.x=pre.x+dir[i][0]; now.y=pre.y+dir[i][1]; now.step=pre.step+1; if(now.ok()&&!vis[now.x][now.y]) { if(now==e) return now.step; now.g=pre.g+22;//这里为√5*10 now.h=Heuristic(now); now.f=now.g+now.h; Q.push(now); vis[now.x][now.y]=1;//标记该点已访问 } } } return -1;}int main(){ char s1[3],s2[3]; while(~scanf("%s%s",s1,s2)) { s.x=s1[0]-'a';s.y=s1[1]-'1'; s.f=s.g=s.h=s.step=0; e.x=s2[0]-'a'; e.y=s2[1]-'1'; int ans=Astar(); printf("To get from %s to %s takes %d knight moves.\n",s1,s2,ans); } return 0;}
之后,我又用BFS做了一下:(从这个题看不出什么差距,可能数据量不大)
Accepted 176K 耗时: 16MS
#include <iostream>#include <cstdio>#include <cstring>#include <queue>using namespace std;int step[8][8];struct node{ int x,y;};int dir[8][2]={{-2,-1},{-2,1},{-1,2},{1,2},{2,1},{2,-1},{1,-2},{-1,-2}};queue <node> q;int BFS(node begin,node end){ memset(step,0,sizeof(step)); while(!q.empty()) q.pop(); node temp,next; q.push(begin); while(!q.empty()) { temp=q.front(); q.pop(); for(int i=0;i<8;i++) { next.x=temp.x+dir[i][0]; next.y=temp.y+dir[i][1]; if(next.x<0||next.x>=8||next.y<0||next.y>=8) continue; if(step[next.x][next.y]>0) continue; step[next.x][next.y]=step[temp.x][temp.y]+1; q.push(next); if(next.x==end.x && next.y==end.y) return step[next.x][next.y]; } } return -1;}int main (){ char s1[3],s2[3]; node begin,end; while(scanf("%s%s",s1,s2)!=EOF) { if(strcmp(s1,s2)==0) { printf("To get from %s to %s takes 0 knight moves.\n",s1,s2); continue; } begin.x=s1[1]-'1';begin.y=s1[0]-'a'; end.x=s2[1]-'1';end.y=s2[0]-'a'; printf("To get from %s to %s takes %d knight moves.\n",s1,s2,BFS(begin,end)); } return 0;}
- poj 2243(A*搜索orBFS)
- poj 2243 a星搜索
- poj 2488 A Knight's Journey(深度优先搜索)
- POJ 2599 A funny game(博弈搜索)
- POJ 1691 Painting A Board(dfs搜索)
- POJ 2488 A Knight's Journey(简单搜索)
- Toj 1116 Poj 1324(A*搜索) Holedox Moving
- poj 2488A Knight's Journey(搜索 记录路径)
- poj-1976 A Mini Locomotive(DP,记忆化搜索)
- POJ 2599 A funny game (搜索,博弈)
- poj 3897 Maze Stretching 二分+A*搜索
- POJ-2415 Hike on a Graph 搜索
- Poj 2488 A Knight's Journey(搜索)
- POJ 2488 A Knight's Journey 搜索
- [POJ 2449] Remmarguts' Date [A*搜索]
- POJ 2488 A Knight's Journey 搜索
- POJ 2488 A Knight's Journey 搜索
- POJ Remmarguts' Date A*搜索+spfa
- Euclid's Game
- 黑马程序员-我的摘录-正则表达式总结-需要加强
- [Android]反编译工具:apktool、dex2jar、jd-gui使用简介
- 第一讲.Liner_Regression and Gradient_Descent(Rui Xia) 单变量线性回归及梯度下降
- hdu4092 计算几何趣味打表题
- poj 2243(A*搜索orBFS)
- ubuntu安装搜狗输入法
- UVa:10664 Luggage
- 杭电 1287 破译密码
- 寻找最好的笔记软件:三强篇(EverNote、Mybase、Surfulater)
- 为什么是Borland C++ Builder?
- 黑马程序员-JAVA基本的语法概念和常识
- Oracle 11g R2的安装和登录方法
- LPWSTR转换为LPCSTR