A*算法——启发式搜索
A*算法
本质还是搜索:加了优化而已
关于这个优化,听到两种说法:
1.剪枝
通过判断预计最少还要几步,加强版剪枝
比如说一个经典剪枝:
如果
步数≥已知最小值
则
剪枝
升级|
V
如果
步数+最少还要几步≥已知最小值
则
剪枝
2.修改顺序
每次搜索时优先考虑最有可能是最有解的选项
(启发的感觉)
可以建个优先队列来维护每次取到的f最小
注:
f=g+h
g为已经用的步数
h为预计要用的步数
——我倾向于这一种,因为感觉更加神奇,而且写出来是非递归(递归的心理阴影)——
下面来一道水题:BFS轻松过的我来写A*
http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=19699 poj3984事实上既然m n都是5,BFS说不定会比A*更优
但是说明问题就好
#include <cstdio>
#include <queue>
#include <cmath>
using namespace std;
struct hh
{
int x,y,z;
};
priority_queue<hh> q;
int n,m,t,x1,yy,x2,y2,_x,_y;
bool ma[][],b[][],c[][];
int f[][],g[][],h[][],fa[][],mo[][];
bool operator <(hh a,hh b)
{
return a.z>b.z;
}
int add(int x,int y,int z)
{
hh p;
p.x=y;p.y=z;p.z=x;
q.push(p);
return ;
}
int check(int x,int y,int z,int ff,int m)
{
if(!ma[x][y])
{
if(b[x][y])
{
if(g[x][y]>z)
{
g[x][y]=z;
f[x][y]=z+h[x][y];
fa[x][y]=ff;
mo[x][y]=m;
add(f[x][y],x,y);
}
}
else
if(!c[x][y])
{
b[x][y]=true;
g[x][y]=z;
h[x][y]=abs(x-x2)+abs(y-y2);
f[x][y]=g[x][y]+h[x][y];
fa[x][y]=ff;
mo[x][y]=m;
add(f[x][y],x,y);
}
}
return ;
}
int a_star()
{
check(x1,yy,,,);
while(!q.empty())
{
int x=q.top().x;
int y=q.top().y;
q.pop();
if((x==x2)&&(y==y2))
return g[x][y];
b[x][y]=false;
c[x][y]=true;
check(x-,y,g[x][y]+,x,y);
check(x,y-,g[x][y]+,x,y);
check(x+,y,g[x][y]+,x,y);
check(x,y+,g[x][y]+,x,y);
}
return ;
}
int print(int x,int y)
{
if(fa[x][y]>)
print(fa[x][y],mo[x][y]);
printf("(%d, %d)\n",x-,y-);
return ;
}
int main()
{
n=;m=;
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
scanf("%d",&ma[i][j]);
x1=;yy=;x2=;y2=;
a_star();
print(,);
return ;
}
代码不是很长,而且因为刚写完别的题,这里只是套了一下,很多代码是多余的
print递归输出不用管
a_star是主要程序(一看就知道)
check用于检查当前点周围一圈的点能不能加入队列,b表示点是否已经加入,c表示该点是否已经退出(已退出的不用管了)
记得在有更优值时更新
其实像是一种更加神奇的Dj——优先级是预计中的全路而不是已搜到的路,让程序能稍稍有点远见前面是坑还是会钻
这样写最神奇的地方在于它会向着目标一头栽过去,而不是像广搜只顾着预定的顺序,更加接近正常人的逻辑,因此搜索范围大大减小。
既然每个点都只能进队列一次,这个算法的复杂度最差情况下还是很低的
A*算法——启发式搜索的更多相关文章
- 启发式搜索A-Star算法 【寻找 最短路径 算法】【地理几何位置 可利用的情况】
在处理最短路径问题时,有一种启发式算法是我们应该了解的,由于其有着优秀的探索效率在各自现实项目中多有应用,它就是 A-star 算法,或 A* 算法. 个人观点: A* 算法并不保证找到的路径一 ...
- 集训Day10
果然颓的不像话 bzoj3680 gty又虐了一场比赛,被虐的蒟蒻们决定吊打gty.gty见大势不好机智的分出了n个分身,但还是被人多势众的蒟蒻抓住了.蒟蒻们将n个gty吊在n根绳子上,每根绳子穿过天 ...
- 启发式搜索A*算法
A* 寻路算法 (2011-02-15 10:53:11) 转载▼ 标签: 游戏 分类: 算法 概述 虽然掌握了 A* 算法的人认为它容易,但是对于初学者来说, A* 算法还是很复杂的. 搜索区域(T ...
- 启发式搜索——A*算法
启发式搜索 启发式搜索是一种对搜索到的每一个位置进行评估,然后从评估的最优位置进行搜索直到目的地, 由于搜索时对每一个位置的评估是基于直观或经验的所有叫启发式搜索 A*算法 历史: 1964年Nils ...
- 启发式搜索 A*算法的OC 实现
前两天重新学习了下A*算法,上次学习A*算法已经是5年前了,看到网上铺天盖地的A*算法都是C.C++等等其他语言的,就是没有OC 的,所以抽空写了一份.今天太晚了就不说明A*算法的细节了,大家如果想学 ...
- js版九宫格拼图与启发式搜索(A*算法)
九宫格拼图游戏大家都很熟悉,这里给大家如介绍何应用状态空间搜索的方式求解拼图的最佳路径和一个游戏dome及自动求解方法: 本文分web版游戏的实现和启发式搜索算法两部分: 先看dome,直接鼠标点击要 ...
- 【启发式搜索】【A*算法】hdu6171 Admiral
一个舰队的目标状态如上图.红色是旗舰.然后给你初始局面,每一次决策可以把旗舰和其上一层或下一层的两个相邻的进行交换.如果能在20步内出解的话,输出最小步数:否则输出“too difficult”. 把 ...
- A*算法
A*在游戏设计中有它很典型的用法,是人工智能在游戏中的代表. A*算法在人工智能中是一种典型的启发式搜索算法,为了说清楚 A*算法,我看还是先说说何谓启发式算法. 一.何谓启发式搜索算法: 在说它之前 ...
- [Evolutionary Algorithm] 进化算法简介
进化算法,也被成为是演化算法(evolutionary algorithms,简称EAs),它不是一个具体的算法,而是一个“算法簇”.进化算法的产生的灵感借鉴了大自然中生物的进化操作,它一般包括基因编 ...
随机推荐
- 常见input输入框 点击 发光白色外阴影 focus
先看看具体实现的效果 第一就是点击input 实现的效果 默认谷歌点击input是蓝色边框 去掉用outline:0; 实现效果用focus 默认状态的边框颜色一般较重 如border:1px s ...
- BerkeleyDB库简介
BerkeleyDB库简介 BerkeleyDB(简称为BDB)是一种以key-value为结构的嵌入式数据库引擎: 嵌入式:bdb提供了一系列应用程序接口(API),调用这些接口很简单,应用程序和b ...
- CF memsql Start[c]UP 2.0 B
CF memsql Start[c]UP 2.0 B B. Distributed Join time limit per test 1 second memory limit per test 25 ...
- 微信公众平台自定义菜单新增扫一扫、发图片、发位置 LBS运作更便捷
今天微信公众平台发布更新,自定义菜单新增扫一扫.发图片.发送位置等功能,这对于有意挖掘微信LBS服务的运营者来说更便捷了,订阅号不用返回微信界面就能扫图.发送图片.调用地理位置,用户体验更友好,自然也 ...
- PHP变量入门教程(2)超全局变量,总共9个
PHP 超全局变量 $GLOBALS 包含一个引用指向每个当前脚本的全局范围内有效的变量.该数组的键标为全局变量的 名称.从 PHP 3 开始存在 $GLOBALS 数组. $_SERVER 变量由 ...
- CDN的特点
CDN的特点 1.本地Cache加速提高了企业站点(尤其含有大量图片和静态页面站点)的访问速度,并大大提高以上性质站点的稳定性(省钱,用户体验提升). 2.镜像服务消除了不同运营商之间的瓶颈造成的影响 ...
- TouchSlide1.1,手机上的幻灯片
TouchSlide 是纯javascript打造的触屏滑动特效插件 http://pan.baidu.com/s/1bpoWNin 官网:http://www.superslide2.com/Tou ...
- java.lang.UnsatisfiedLinkError: Couldn't load BaiduMapSDK 的解决方法
遇到找不到so的同学们可以先从以下几个方面来检查问题: 1.so的名字是不是被修改了?我们SDK的so名字是固定的,如果您自行对它进行了重命名操作,那肯定是没法找到so的.2.so放置位置不对.so需 ...
- linux 用户创建、管理、权限分配
(1)su与sudo su:通过su可以在用户之间切换,如果超级权限用户root向普通或虚拟用户切换不需要密码,什么是权力?这就是!而普通用户切换到其它任何用户都需要密码验证: sudo: sudo扮 ...
- Servlet 之 ServletContext
package cn.jiemoxiaodi.servlet_servletcontext; import java.io.IOException; import java.io.PrintWrite ...