A*算法的原理和实现
一:A*的介绍
A*算法是一种启发式搜索算法,就是在状态空间中的搜索对每一个搜索的位置进行评估,得到最好的位置,再从这个位置进行搜索直到目标。这样可以省略大量无畏的搜索路径,提到了效率。在启发式搜索中,对位置的估价是十分重要的。采用了不同的估价可以有不同的效果。
该算法可以用公式f(n)=g(n)+h(n)表示,其中 f(n) 是从初始点经由节点n到目标点的估价函数,g(n) 是在状态空间中从初始节点到n节点的实际代价,h(n) 是从n到目标节点最佳路径的估计代价。h*(n)是从n到目标节点最佳路径的实际代价,那么整个个启发式搜索过程必须保证h(n)<=h*(n),否则搜索出错。
对于h(n) 的选择,越接近h*(n)则速度越快。
主要有以下几种启发函数
曼哈顿距离:
定义曼哈顿距离的正式意义为L1-距离或城市区块距离,也就是在欧几里德空间的固定直角坐标系上两点所形成的线段对轴产生的投影的距离总和。例如在平面上,坐标(x1,y1)的点P1与坐标(x2, y2)的点P2的曼哈顿距离为:|x1 - x2| + |y1 - y2|。
欧氏距离:
是一个通常采用的距离定义,它是在m维空间中两个点之间的真实距离。在二维和三维空间中的欧氏距离的就是两点之间的距离。例如在平面上,坐标(x1,y1)的点P1与坐标(x2, y2)的点P2的欧氏距离为: sqrt((x1-x2)^2+(y1-y2)^2 )。
切比雪夫距离:
是两个向量之间各分量差值的最大值。例如在平面上,坐标(x1, y1)的点P1与坐标(x2, y2)的点P2的切比雪夫距离为:max(|x1 - x2| , |y1 - y2|)。
二:A*算法的过程
目标:要从A走到P,节点后的是估值
搜索过程中设置两个表:OPEN和CLOSED。OPEN表保存了所有已生成而未考察的节点,CLOSED表中记录已访问过的节点。算法中有一步是根据估价函数重排OPEN表。这样循环中的每一步只考虑OPEN表中状态最好的节点。具体搜索过程如下:
1)初始状态:
OPEN=[A5];CLOSED=[];
2)估算A5,取得搜有子节点,并放入OPEN表中;
OPEN=[B4,C4,D6];CLOSED=[A5]
3)估算B4,取得搜有子节点,并放入OPEN表中;
OPEN=[C4,E5,F5,D6];CLOSED=[B4,A5]
4)估算C4;取得搜有子节点,并放入OPEN表中;
OPEN=[H3,G4,E5,F5,D6];CLOSED=[C4,B4,A5]
5)估算H3,取得搜有子节点,并放入OPEN表中;
OPEN=[O2,P3,G4,E5,F5,D6];CLOSED=[H3,C4,B4,A5]
6)估算O2,取得搜有子节点,并放入OPEN表中;
OPEN=[P3,G4,E5,F5,D6];CLOSED=[O2,H3,C4,B4,A5]
7)估算P3,已得到解;
其中,OPEN表可以用优先队列实现
代码:
POJ2243
在棋盘上,骑士走“日”的形态,求从棋盘一点到另外一点的最短步数?
#include<stdio.h>
#include<queue>
#include<string.h>
#include<math.h>
using namespace std;
int a[8][2]={{-2,-1},{-2,1},{-1,-2},{-1,2},{1,-2},{1,2},{2,-1},{2,1}},vist[9][9];
struct node
{ int x,y,step; int f,g,h; bool operator < (const node &anOther) const { return f > anOther.f; }
};
node s,e; int find_h(node tmp){ double a;a=((e.x-tmp.x)^2+(e.y-tmp.y)^2);int b=sqrt(a);return b*10;
}
priority_queue<node>que; int AStar(node start,node end)
{ int i; node cur,next; while( !que.empty() ) que.pop(); que.push(start); while( !que.empty() ) { cur = que.top(); que.pop(); for(i=0;i<8;i++) { next.x = cur.x + a[i][0]; next.y = cur.y + a[i][1]; if( !vist[next.x][next.y] && next.x>=1 && next.x<=8 && next.y>=1 && next.y<=8 ) { vist[ next.x ][ next.y ] = 1; next.step = cur.step + 1; next.g = cur.g +23; next.h = find_h(next); next.f = next.g + next.h; if(next.x == end.x && next.y == end.y ) return next.step; que.push(next); } } } return 0;
} int main()
{ int move; char t,m; while( scanf("%c%d %c%d",&t,&s.y,&m,&e.y) !=EOF) { getchar(); memset(vist,0,sizeof(vist)); move = 0; s.x = t - 'a' + 1; e.x = m - 'a' + 1; s.step = 0; s.g = 0; s.f = s.g + find_h(s); vist[s.x][s.y]=1; move = AStar(s,e); printf("To get from %c%d to %c%d takes %d knight moves.\n",t,s.y,m,e.y,move); } return 0;
}
A*算法的原理和实现相关推荐
- deeplearning算法优化原理
deeplearning算法优化原理 目录 • 量化原理介绍 • 剪裁原理介绍 • 蒸馏原理介绍 • 轻量级模型结构搜索原理介绍 Quantization Aware Training量化介绍 1.1 ...
- 【机器学习入门】(1) K近邻算法:原理、实例应用(红酒分类预测)附python完整代码及数据集
各位同学好,今天我向大家介绍一下python机器学习中的K近邻算法.内容有:K近邻算法的原理解析:实战案例--红酒分类预测.红酒数据集.完整代码在文章最下面. 案例简介:有178个红酒样本,每一款红酒 ...
- 前景背景分割——ostu算法的原理及实现 OpenCV (八)
OpenCV [八]--前景背景分割--ostu算法的原理及实现 实验结果 代码实现 实现原理 参考资料 实验结果 代码实现 #include<opencv2/opencv.hpp> #i ...
- 视觉SLAM开源算法ORB-SLAM3 原理与代码解析
来源:深蓝学院,文稿整理者:何常鑫,审核&修改:刘国庆 本文总结于上交感知与导航研究所科研助理--刘国庆关于[视觉SLAM开源算法ORB-SLAM3 原理与代码解析]的公开课. ORB-SLA ...
- 神经网络感知器算法调整原理是什么
算法调整原理 如果点分类正确,则什么也不做. 如果点分类为正,但是标签为负,则分别减去 αp,αq, 和 α 至 w_1, w_2,w1,w2, 和 bb 如果点分类为负,但是标签为正,则分别将α ...
- Adaboost 算法的原理与推导
Adaboost 算法的原理与推导 0 引言 一直想写Adaboost来着,但迟迟未能动笔.其算法思想虽然简单:听取多人意见,最后综合决策,但一般书上对其算法的流程描述实在是过于晦涩.昨日11月1日下 ...
- layer output 激活函数_一文彻底搞懂BP算法:原理推导+数据演示+项目实战(下篇)...
在"一文彻底搞懂BP算法:原理推导+数据演示+项目实战(上篇)"中我们详细介绍了BP算法的原理和推导过程,并且用实际的数据进行了计算演练.在下篇中,我们将自己实现BP算法(不使用第 ...
- TCP协议、算法和原理
TCP是一个巨复杂的协议,因为他要解决很多问题,而这些问题又带出了很多子问题和阴暗面.所以学习TCP本身是个比较痛苦的过程,但对于学习的过程却能让人有很多收获. 关于TCP这个协议的细节,我还是推荐你 ...
- PageRank算法--从原理到实现
本文将介绍PageRank算法的相关内容,具体如下: 1.算法来源 2.算法原理 3.算法证明 4.PR值计算方法 4.1 幂迭代法 4.2 特征值法 4.3 代数法 5.算法实现 5.1 基于迭代法 ...
- DCT算法的原理及实现简介
DCT算法的原理及实现简介 DCT算法: DCT变换的全称是离散余弦变换(Discrete Cosine Transform),离散余弦变换相当于一个长度大概是它两倍的离散傅里叶变换,这个离散傅里叶变 ...
最新文章
- linux监控平台介绍、zabbix监控介绍、安装zabbix
- ue4 无限地图_RPG游戏开发日志13:无限地图的实现
- caddy php sock,Caddy环境下一些Web应用程序的配置参考
- python爬虫代码提取图片中的文字_python识别图像并提取文字的实现方法
- Udacity并行计算课程笔记-The GPU Hardware and Parallel Communication Patterns
- 基于 Windows Mobile 的 Pocket PC 和 Smartphone 的开发工具简介
- 一个C++工程CPU占用100%问题的排查
- javaHTTP通信---get方式
- Docker Toolbox下配置国内镜像源-阿里云加速器
- 弦截法及Python实现
- 嵌入式软件工程师自学之路
- 在unity中更改天空盒的几种方式
- github博客Hexo引流到微信
- Nginx配置项优化详解
- 安装Anaconda3以及如何使用Jupyter
- matplotlib eps格栅化,透明度被改变的问题 pdf->eps
- 如何把图片无损放大?教你图片怎么无损放大
- 西瓜书决策树实现(基于ID3)——采用字典数据结构
- Oracle Golden Gate(OGG)学习——源端安装OGG (数据库版本为Oracle 10g)
- PS笔刷:太空星云特效