八数码难题 (IDA*解法)
翻题解的时候看到大佬们都打的双向广搜。(蒟蒻在墙角瑟瑟发抖
在这里提供一种IDA*解法,
还是一层层地搜索,如果超出预期层数就返回
然后用评估函数进行剪枝(就是可行性剪枝)
感觉写起来比双向广搜好多了
评估函数越好,搜索效率越高;
如果评估函数太差,那IDA*和普通爆搜复杂度差不多。
所有一个好的评估函数很关键;
主要是看这道题评估函数(h)怎么写,
对于评估函数想到的有两个方案:
方案一:不在自己应在位置上数的个数;
方案二:所有数距自己应在位置的曼哈顿距离之和;
很显然选第二个方案更优,(虽然方案一也可以AC)
因为一个数移动到自己目标位置,至少要移动它现在位置到它目标位置的曼哈顿距离
例如下面这一个
它的距原状态的曼哈顿距离和就是4(1+1+2)
(不用计算0,因为其它数字归位后,0也会回到原位)
至于如何实现,可以先开一个数组记录任意两位置之间的曼哈顿距离
然后再开一个数组记录每个数字目标状态的位置
大概是这样的
int dis[9][9]={{0,1,2,1,2,3,2,3,4},{1,0,1,2,1,2,3,2,3},{2,1,0,3,2,1,4,3,2},{1,2,3,0,1,2,1,2,3},{2,1,2,1,0,1,2,1,2},{3,2,1,2,1,0,3,2,1},{2,3,4,1,2,3,0,1,2},{3,2,3,2,1,2,1,0,1},{4,3,2,3,2,1,2,1,0}
}; //两个位置间的曼哈顿距离
int yuan[9]={4,0,1,2,5,8,7,6,3};//每个数字的目标位置
int chu[3][3];//存储现在状态
int h()
{int ans=0;for(int i=0;i<3;i++)for(int j=0;j<3;j++){if(chu[i][j]==0) continue;ans+=dis[yuan[chu[i][j]]][i*3+j];//i*3+j表示数字现在位置}return ans;
}
这样我们的评估函数就写好啦!
然后搜索。
具体细节在代码里说明。(码风有点丑,见谅QAQ)
#include<bits/stdc++.h>
using namespace std;
int dis[9][9]={{0,1,2,1,2,3,2,3,4},{1,0,1,2,1,2,3,2,3},{2,1,0,3,2,1,4,3,2},{1,2,3,0,1,2,1,2,3},{2,1,2,1,0,1,2,1,2},{3,2,1,2,1,0,3,2,1},{2,3,4,1,2,3,0,1,2},{3,2,3,2,1,2,1,0,1},{4,3,2,3,2,1,2,1,0}
}; //两个位置间的曼哈顿距离
int yuan[9]={4,0,1,2,5,8,7,6,3};//每个数字的目标位置
int chu[3][3];//存储现在状态
inline int h()
{int ans=0;for(int i=0;i<3;i++)for(int j=0;j<3;j++){if(chu[i][j]==0) continue;//不考虑0ans+=dis[yuan[chu[i][j]]][i*3+j];//i*3+j表示数字现在位置}return ans;
}
int ax[4]={0,-1,1,0};
int ay[4]={1,0,0,-1};//这两个数组一定要对称写,使搜索时不会返回上一状态
bool flag;
void dfs(int ceng,int dep,int f,int x,int y)//f表示上一次转移的方向
{int nx,ny;if(ceng==dep) //如果搜到了预期层数{if(!h()) flag=1;//如果达到了目标状态return;}for(int i=0;i<4;i++){nx=x+ax[i];ny=y+ay[i];if(nx<0||ny<0||nx>=3||ny>=3) continue;//出界if(i+f==3) continue;//如果会返回上一个状态swap(chu[nx][ny],chu[x][y]);if(ceng+h()<=dep)//如果最优情况都会超出预期,就直接返回dfs(ceng+1,dep,i,nx,ny);if(flag) return;//找到解就直接返回swap(chu[nx][ny],chu[x][y]);//回溯}return;
}
int main()
{char k;int sx,sy;for(int i=0;i<3;i++){for(int j=0;j<3;j++){cin>>k;chu[i][j]=k-'0';if(k=='0') {sx=i;sy=j;//初始0的位置}}}if(!h())//特判,如果一开始就达到目标,直接结束{cout<<0;return 0;}flag=0;int maxdep;//预期深度for(maxdep=1;;maxdep++)//一层一层地搜{dfs(0,maxdep,-1,sx,sy);//一开始没有方向,所以传入-1if(flag)//找到解{cout<<maxdep<<endl;break;} }return 0;//愉快结束
}
好像跑的挺快的
双向广搜是不可能打的,这辈子都不可能打的
八数码难题 (IDA*解法)相关推荐
- 八数码难题的多种解法
蔡自兴老师的<人工智能及其应用>这本书的第3章里面讲解了很多种搜索方法,因为看的不是很懂,所以网上就找了资源来帮助理解. 为了帮助各位更好的理解,在此,仅以八数码难题为实例来解释说明. # ...
- 习题:八数码难题(双向BFS)
八数码难题(wikioi1225) [题目描述] 在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字.棋盘中留有一个空格,空格用0来表示.空格周围的棋子可以移到空格中.要求解的问题是:给出 ...
- 【codevs1225】八数码难题,如何精确地搜索
1225 八数码难题 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 题目描述 Description Yours和zero在研究A*启发式算法.拿到一道 ...
- 洛谷P1379八数码难题
题目描述 在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字.棋盘中留有一个空格,空格用0来表示.空格周围的棋子可以移到空格中. 要求解的问题是:给出一种初始布局(初始状态)和目标布局(为 ...
- 利用Python求解八数码难题
实验目的 实验内容 八数码问题也称为九宫问题.在3×3的棋盘,摆有八个棋子,每个棋子上标有1至8的某一数字,不同棋子上标的数字不相同.棋盘上还有一个空格,与空格相邻的棋子可以移到空格中.要求解决的问题 ...
- 深度优先搜索解决八数码难题
八数码问题 以前用java写的通过深度优先瘦素解决八数码难题. 对于八数码难题来说,可以把9宫格看成一个[3][3]的二维数组,将空格位置看成0,将0可以移动的方向看成树的枝丫,分为上下左右4个方向. ...
- 8puzzle java 代码_八数码难题(8 puzzle)深度优先和深度优先算法
1搜索策略 搜索策略是指在搜索过程中如何选择扩展节点的次序问题.一般来说,搜索策略就是采用试探的方法.它有两种类型:一类是回溯搜索,另一类是图搜索策略. 2盲目的图搜索策略 图搜索策略又可分为两种:一 ...
- 1379 八数码难题
1379 八数码难题 这道题我本来想使用HASH+MAP来练练手,结果发现用A*+ID更简单 也就是说,这道题使用的是A算法+迭代加深算法进行一个估价函数和固定层数再加上优化的时间,来AC这一道题 首 ...
- 洛谷—P1379 八数码难题
题目链接:P1379 八数码难题 题目大意: 要求最少步骤的移动方法,实现从初始布局到目标布局的转变. 解题思路: 这道题目要用到搜索中比较难的搜索方法-迭代加深的A*算法.所谓迭代加深就是每次限制搜 ...
最新文章
- 2021年春季学期-信号与系统-第四次作业参考答案-第八小题
- python扩展包安装_python怎么安装扩展包
- Oralce删除多个表
- 独家 | 揭秘2021双11背后的数据库硬核科技
- springboot data.redis.RedisConnectionFactory 集成问题
- vxWorks下常用的几种延时方法
- plsql 误删表,使用flashback query恢复被删除plsql
- 每日一道算法题--leetcode 179--最大数--python
- 关于Tortoise git汉化包装了,不管用,仍然是英文菜单的问题记录
- bzoj3625:[Codeforces Round #250]小朋友和二叉树
- python的分隔符_python分隔符
- 第7章 CustomView绘图进阶
- 两难选择:继续工作还是考研
- Qt保存Excel格式数据
- 视频号主页,实现一键添加个人微信功能,留客更方便,真香
- 测试壁纸相机软件叫什么,如何检测照片的拍摄角度,以及如何像查看桌面应用程序一样自动旋转以显示网站?...
- 【转载】HTML 编辑器
- 网段和子网掩码及IP个数的计算
- MyBatis一级缓存和二级缓存
- 保姆级zookeeper集群搭建(leader+follower模式)
热门文章
- 佳能相机断电DAT文件有大小无法播放的修复方法
- cpu软改vista 驱动_在Windows 7、8或Vista中启动分配给特定CPU的应用程序
- 合并多个HEX文件的方法
- python3.6.5安装包下载_Python3.6.5安装包 32/64位 官方免费版
- android 炫酷的自定义轮播图,Android实现炫酷轮播图效果
- 《劳动合同法》解读|新劳动合同法解析列表
- Python整数类型
- TP4056大电流1A使用注意事项
- oracle分页改写为mysql_mysql和oracle分页
- WordPress:自定义头像