启发式搜索——A*算法
启发式搜索
启发式搜索是一种对搜索到的每一个位置进行评估,然后从评估的最优位置进行搜索直到目的地,
由于搜索时对每一个位置的评估是基于直观或经验的所有叫启发式搜索
A*算法
历史:
1964年Nils Nilsson提出了A1算法,是一个启发式搜索算法,
而后又被改进成为A2算法,直到1968年,被Peter E. Hart改进成为A*算法
主要思想:
1.对于每个搜索到的点求一个估价函数f(x)。
$\large f(x)=g(x)+h(x)$
其中g(x)表示起点到当前点实际走的代价,h(x)表示当前点x到终点的估算代价。
2.并将这个搜索到的点按f(x)加入一个待搜索列表中。
3.每次从待搜索列表取出f(x)最小的点加入搜索过列表,并从这个点开始进行搜索
4.重复1。
注意:如果搜索到的一个点已经在待搜索列表(在搜索过列表不算)中
则要更新它的f值,而不是什么也不做,因为可能出现下面这种情况

红色为起点,绿色为终点,灰色为搜索过列表中的点,黄色为待搜索列表中的点,蓝色的是障碍。
如果按和终点的曼哈顿距离算h(x)则会搜索成这种情况,
这时被圈出的黄色的点g(x)=被圈出的灰色的点的g(x)+1。
这显然不是最优的g值
所以搜索时在遇到待搜索列表中的点要更新它的f值
h函数的选择
由于h函数只是一个估计值,所以对于每个题目可以有许多h函数的选择方法
选择不同的h函数会有不同的效果,但大致有两条规律:
- 如果h(x)>x到终点的实际代价,则可以尽快找到一个解,但不一定是最优解
- 如果$h(x)\le$x到终点的实际代价,则如果有解,一定是最优解
且h(x)和x到终点的实际代价相差越大,搜到的无关节点越多
例题
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
#include<cstring>
using namespace std;
const int fac[]={, , , , , , , , };
int cantor(int a[],int k){//康托展开
int ans=,tmp;
for(int i=;i<k;i++){
tmp=;
for(int j=i+;j<k;j++){
if(a[i]>a[j])tmp++;
}
ans+=tmp*fac[k-i-];
}
return ans;
}
void uncantor(int a[],int k,int num){//逆康托展开
int b[];
for(int i=;i<k;i++)b[i]=i+;
b[k]=;
for(int i=,x;i<k;i++){
x=num/fac[k-i-],num%=fac[k--i];
a[i]=b[x]-;
for(int j=x;b[j];j++)b[j]=b[j+];
}
}
int ma,dis[][],go[][]={{,},{-,},{,},{,-}},a[],b[];
bool vis[];
int h(){//估价代价
int ans=;
for(int i=,j;i<;i++){
for(j=;j<;j++){
if(a[i]==b[j])break;
}
if(a[i])ans+=dis[i][j];
}
return ans;
}
struct Node{
int x,f,g;//x为状态的康托展开值,
bool operator < (const Node &b)const{
return f>b.f;
}
}node,w;
priority_queue<Node> q;
int astr(int now,int t){//A*算法
node.x=now;
node.f=h();
node.g=;
q.push(node);
while(!q.empty()){
w=q.top(),q.pop();
if(vis[w.x])continue;
vis[w.x]=;
if(w.x==t){
return w.f;
}
uncantor(a,,w.x);
int x,y;
for(int i=;i<;i++){
if(a[i]==){
x=i/,y=i%;break;
}
}
for(int i=;i<;i++){
int x1=x+go[i][],y1=y+go[i][];
if(x1>=&&x1<&&y1>=&&y1<){
swap(a[x1*+y1],a[x*+y]);
node.x=cantor(a,),node.g=w.g+,node.f=h()+node.g;
if(!vis[node.x])q.push(node);
swap(a[x1*+y1],a[x*+y]);
}
}
}
return ;
}
int main(){
char s[];int st,t;
sscanf("","%s",s);
for(int i=;i<;i++)b[i]=s[i]^0x30;
t=cantor(b,);
scanf("%s",s);
for(int i=;i<;i++)a[i]=s[i]^0x30;
st=cantor(a,);
vis[st]=;
for(int i=;i<;i++){
for(int j=i+;j<;j++){
dis[j][i]=dis[i][j]=j/-i/+abs(i%-j%);
}
}
memset(vis,,sizeof(vis));
printf("%d",astr(st,t));
return ;
}
IDA*
A*算法和bfs一样都要记录每个节点是否被访问过了,有些题目的状态不好表示
使用A*算法就会非常麻烦,这时就可以使用IDDFS的A*思想优化版IDA*(IDA*并不是迭代加深A*)
具体操作
具体操作和IDDFS基本一样:
- 确定一个限制深度,然后进行DFS
- 如果在限制深度内得不到解就将限制深度加深,继续DFS
- 如果得到解就输出
只是在dfs的时候利用A*思想估计剩余深度,如果当前深度+估计值>限制深度就退出本次搜索
/******************************************************************
IDA*
******************************************************************/
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int center[] = {,,,,,,,}; //中心8个点的位置
const int reversetp[] = {,,,,,,,}; //每种操作的逆操作
const int op[][] = { //从A-H操作的值的下标
{ , , ,,,, }, //A
{ , , ,,,, }, //B
{ , , , , , , }, //C
{ ,,,,,, }, //D
{ ,,,, , , }, //E
{ ,,,, , , }, //F
{ ,,,,,, }, //G
{ , , , , , , }, //H
};
int a[];
int h(){
int num[]={};
for(int i=;i<;i++){
num[a[center[i]]-]++;
}
return -max(num[],max(num[],num[]));
}
bool f;char ans[];
void modify(int x){
int w=a[op[x][]];
for(int i=;i<;i++)a[op[x][i]]=a[op[x][i+]];
a[op[x][]]=w;
}
void idastar(int d,int maxd){
if(f)return;
if(d==maxd){
if(!h())f=,ans[d]=,printf("%s\n%d\n",ans,a[]);
return;
}
if(d>maxd||d+h()>maxd)return;
for(int i=;i<;i++){
modify(i);
ans[d]=(i^0x40)+,idastar(d+,maxd);
modify(reversetp[i]);
}
}
void work(){
for(int i=;i<;i++)scanf("%d",a+i);
if(!h()){
printf("No moves needed\n%d\n",a[]);
return;
}
f=;
for(int i=;;i++){
idastar(,i);
if(f)return;
}
}
int main(){
while(~scanf("%d",a)&&a[])work();
return ;
}
启发式搜索——A*算法的更多相关文章
- 启发式搜索A*算法
A* 寻路算法 (2011-02-15 10:53:11) 转载▼ 标签: 游戏 分类: 算法 概述 虽然掌握了 A* 算法的人认为它容易,但是对于初学者来说, A* 算法还是很复杂的. 搜索区域(T ...
- 启发式搜索A-Star算法 【寻找 最短路径 算法】【地理几何位置 可利用的情况】
在处理最短路径问题时,有一种启发式算法是我们应该了解的,由于其有着优秀的探索效率在各自现实项目中多有应用,它就是 A-star 算法,或 A* 算法. 个人观点: A* 算法并不保证找到的路径一 ...
- 启发式搜索 A*算法的OC 实现
前两天重新学习了下A*算法,上次学习A*算法已经是5年前了,看到网上铺天盖地的A*算法都是C.C++等等其他语言的,就是没有OC 的,所以抽空写了一份.今天太晚了就不说明A*算法的细节了,大家如果想学 ...
- A*搜寻算法(A星算法)
A*搜寻算法[编辑] 维基百科,自由的百科全书 本条目需要补充更多来源.(2015年6月30日) 请协助添加多方面可靠来源以改善这篇条目,无法查证的内容可能会被提出异议而移除. A*搜索算法,俗称A星 ...
- 【算法入门】深度优先搜索(DFS)
深度优先搜索(DFS) [算法入门] 1.前言深度优先搜索(缩写DFS)有点类似广度优先搜索,也是对一个连通图进行遍历的算法.它的思想是从一个顶点V0开始,沿着一条路一直走到底,如果发现不能到达目标解 ...
- 深度优先搜索(DFS)
[算法入门] 郭志伟@SYSU:raphealguo(at)qq.com 2012/05/12 1.前言 深度优先搜索(缩写DFS)有点类似广度优先搜索,也是对一个连通图进行遍历的算法.它的思想是从一 ...
- POJ 2449 Remmarguts' Date --K短路
题意就是要求第K短的路的长度(S->T). 对于K短路,朴素想法是bfs,使用优先队列从源点s进行bfs,当第K次遍历到T的时候,就是K短路的长度. 但是这种方法效率太低,会扩展出很多状态,所以 ...
- dfs介绍
深度优先搜索(DFS) [算法入门] 郭志伟@SYSU:raphealguo(at)qq.com 2012/05/12 1.前言 深度优先搜索(缩写DFS)有点类似广度优先搜索,也是对一个连通图进行遍 ...
- 数据结构6——DFS
一.相关定义 深度优先遍历,也有称为深度优先搜索,简称DFS.其实,就像是一棵树的前序遍历. 初始条件:图G所有顶点均未被访问过,任选一点v. 思想:是从一个顶点V1开始,沿着一条路一直走到底,如果发 ...
随机推荐
- yii2 vendor/bower/jquery/dist not exist
查看 vendor 文件夹,只有bower-asset文件夹 手动修改 bower-asset 为bower 倒也可以,yii2项目每次 composer install 成功之后,每次重命名这个文件 ...
- css---7自定义字体
1.Adobe illustrator AI是一种应用于出版.多媒体和在线图像的工业标准矢量插画的软件,是一款非常好的矢量图形处理工具. 该软件主要应用于印刷出版.海报书籍排版.专业插画.多媒体图像处 ...
- thinkphp 模型定义
模型定义 模型类并非必须定义,只有当存在独立的业务逻辑或者属性的时候才需要定义. 模型类通常需要继承系统的\Think\Model类或其子类,下面是一个Home\Model\UserModel类的定义 ...
- day 58 Django基础六之ORM中的锁和事务
Django基础六之ORM中的锁和事务 本节目录 一 锁 二 事务 三 xxx 四 xxx 五 xxx 六 xxx 七 xxx 八 xxx 一 锁 行级锁 select_for_update( ...
- python+appium真机运行登录例子
一.手机USB连接电脑(手机打开调试模式) 验证:cmd -> 输入adb devices,查看手机的UDID.显示如下表示 连接成功 二.启动Appium服务 1. 启动Appium,点击 右 ...
- Git 比较两个分支之间的差异
1.查看 dev 有,而 master 中没有的: git log dev ^master 2.查看 dev 中比 master 中多提交了哪些内容: git log master..dev 注意,列 ...
- 使用Python实现不同目录下文件的拷贝
目标:要实现将一台计算机的共享文件夹中的文件备份到另一台计算机,如果存在同名的文件只要文件的大小和最后修改时间一致,则不拷贝该文件 python版本:Python3.7.1 python脚本: fro ...
- appium + python 自动化调试手机时 UiAutomator exited unexpectedly with code 0, signal null
放上appium报错图,appium在手机里安装了appium setting 和unlock 软件,输入法也被变成了appium input ,但是就是点不到目标软件,手机也可以被cmd adb ...
- unittest零碎知识
给unittest传值: class TesCase(unittest.TestCase): # k1 = expect = msg = None # requests的返回结果和用例的预期值 def ...
- PropertyPlaceholderConfigurer的注意事项
1.基本的使用方法是<bean id="propertyConfigurerForWZ" class="org.springframework.beans.fact ...