翻题解的时候看到大佬们都打的双向广搜。(蒟蒻在墙角瑟瑟发抖

在这里提供一种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*解法)相关推荐

  1. 八数码难题的多种解法

    蔡自兴老师的<人工智能及其应用>这本书的第3章里面讲解了很多种搜索方法,因为看的不是很懂,所以网上就找了资源来帮助理解. 为了帮助各位更好的理解,在此,仅以八数码难题为实例来解释说明. # ...

  2. 习题:八数码难题(双向BFS)

    八数码难题(wikioi1225) [题目描述] 在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字.棋盘中留有一个空格,空格用0来表示.空格周围的棋子可以移到空格中.要求解的问题是:给出 ...

  3. 【codevs1225】八数码难题,如何精确地搜索

    1225 八数码难题 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 题目描述 Description Yours和zero在研究A*启发式算法.拿到一道 ...

  4. 洛谷P1379八数码难题

    题目描述 在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字.棋盘中留有一个空格,空格用0来表示.空格周围的棋子可以移到空格中. 要求解的问题是:给出一种初始布局(初始状态)和目标布局(为 ...

  5. 利用Python求解八数码难题

    实验目的 实验内容 八数码问题也称为九宫问题.在3×3的棋盘,摆有八个棋子,每个棋子上标有1至8的某一数字,不同棋子上标的数字不相同.棋盘上还有一个空格,与空格相邻的棋子可以移到空格中.要求解决的问题 ...

  6. 深度优先搜索解决八数码难题

    八数码问题 以前用java写的通过深度优先瘦素解决八数码难题. 对于八数码难题来说,可以把9宫格看成一个[3][3]的二维数组,将空格位置看成0,将0可以移动的方向看成树的枝丫,分为上下左右4个方向. ...

  7. 8puzzle java 代码_八数码难题(8 puzzle)深度优先和深度优先算法

    1搜索策略 搜索策略是指在搜索过程中如何选择扩展节点的次序问题.一般来说,搜索策略就是采用试探的方法.它有两种类型:一类是回溯搜索,另一类是图搜索策略. 2盲目的图搜索策略 图搜索策略又可分为两种:一 ...

  8. 1379 八数码难题

    1379 八数码难题 这道题我本来想使用HASH+MAP来练练手,结果发现用A*+ID更简单 也就是说,这道题使用的是A算法+迭代加深算法进行一个估价函数和固定层数再加上优化的时间,来AC这一道题 首 ...

  9. 洛谷—P1379 八数码难题

    题目链接:P1379 八数码难题 题目大意: 要求最少步骤的移动方法,实现从初始布局到目标布局的转变. 解题思路: 这道题目要用到搜索中比较难的搜索方法-迭代加深的A*算法.所谓迭代加深就是每次限制搜 ...

最新文章

  1. 2021年春季学期-信号与系统-第四次作业参考答案-第八小题
  2. python扩展包安装_python怎么安装扩展包
  3. Oralce删除多个表
  4. 独家 | 揭秘2021双11背后的数据库硬核科技
  5. springboot data.redis.RedisConnectionFactory 集成问题
  6. vxWorks下常用的几种延时方法
  7. plsql 误删表,使用flashback query恢复被删除plsql
  8. 每日一道算法题--leetcode 179--最大数--python
  9. 关于Tortoise git汉化包装了,不管用,仍然是英文菜单的问题记录
  10. bzoj3625:[Codeforces Round #250]小朋友和二叉树
  11. python的分隔符_python分隔符
  12. 第7章 CustomView绘图进阶
  13. 两难选择:继续工作还是考研
  14. Qt保存Excel格式数据
  15. 视频号主页,实现一键添加个人微信功能,留客更方便,真香
  16. 测试壁纸相机软件叫什么,如何检测照片的拍摄角度,以及如何像查看桌面应用程序一样自动旋转以显示网站?...
  17. 【转载】HTML 编辑器
  18. 网段和子网掩码及IP个数的计算
  19. MyBatis一级缓存和二级缓存
  20. 保姆级zookeeper集群搭建(leader+follower模式)

热门文章

  1. 佳能相机断电DAT文件有大小无法播放的修复方法
  2. cpu软改vista 驱动_在Windows 7、8或Vista中启动分配给特定CPU的应用程序
  3. 合并多个HEX文件的方法
  4. python3.6.5安装包下载_Python3.6.5安装包 32/64位 官方免费版
  5. android 炫酷的自定义轮播图,Android实现炫酷轮播图效果
  6. 《劳动合同法》解读|新劳动合同法解析列表
  7. Python整数类型
  8. TP4056大电流1A使用注意事项
  9. oracle分页改写为mysql_mysql和oracle分页
  10. WordPress:自定义头像