十六宫格拼图(A*/IDA*)(曼哈顿距离)
传送门
迭代加深:通过单纯的深度优先搜索无法找出初始状态到最终状态的最短路径,但是重复进行限制最大深度的深度优先搜索(深度受限搜索)却可以。简单来说,就是在循环执行深度受限搜索的过程中逐步增加限制值limit,直到找到解为止,这种算法称为迭代加深(Iterative Deepending)
IDA*
在迭代加深中,通过推测值进行剪枝处理的算法称为迭代加深A*或者IDA*。这里的推测值又称为启发通常可以取完成目标所需要的下限值。
对于十六宫格来说,如果能预估出当前状态到最终状态的最小成本h,我们就可以对搜索范围进行剪枝了,也就是说,如果当前状态的深度g加上最小成本h(即“从这里开始至少还需要h次状态迁移)超过了限制深度d,就可以直接中断搜索。
A*
推测值同样适用于以含有优先级队列的迪克斯特拉(或者广度优先搜索)为基础的算法,这类算法称为A*算法,它用优先级队列管理状态,优先对”起点到当前成本+当前位置到目标状态的推测值“最小的状态进行状态迁移,可以更快的找到解。
曼哈顿距离
曼哈顿距离指的是”不进行任何斜向移动,仅仅进行上下左右移动所测出的2点之间的总距离
IDA*
#include<bits/stdc++.h>using namespace std;#define N 4
#define N2 16
#define LIMIT 100const int dx[4]={0,-1,0,1};
const int dy[4]={1,0,-1,0};
const char dir[4]={'r','u','l','d'};int MDT[N2][N2];struct puzzle{int f[N2],space,MD;
};puzzle state;
int limit;
int path[LIMIT];int getALLMD(puzzle pz)
{int sum=0;for(int i=0;i<N2;i++){if(pz.f[i]==N2){continue;}sum+=MDT[i][pz.f[i]-1];}return sum;
}bool dfs(int depth,int prev)
{if(state.MD==0){return true;}if(depth+state.MD>limit){return false;}int sx=state.space/N;int sy=state.space%N;puzzle tmp;for(int r=0;r<4;r++){int tx=sx+dx[r];int ty=sy+dy[r];if(tx<0||ty<0||tx>=N||ty>=N){continue;}//防止重复if(max(prev,r)-min(prev,r)==2){continue;}tmp=state;//计算曼哈顿距离的差值,同时交换拼图块state.MD-=MDT[tx*N+ty][state.f[tx*N+ty]-1];state.MD+=MDT[sx*N+sy][state.f[tx*N+ty]-1];swap(state.f[tx*N+ty],state.f[sx*N+sy]);state.space=tx*N+ty;if(dfs(depth+1,r)){path[depth]=r;return true;}state=tmp;}return false;
}string iterative_deepening(puzzle in)
{in.MD=getALLMD(in);//初始状态的曼哈顿距离for(limit=in.MD;limit<=LIMIT;limit++){state=in;if(dfs(0,-100)){string ans="";for(int i=0;i<limit;i++){ans+=dir[path[i]];}return ans;}}return "unsolvable";
}int main()
{for(int i=0;i<N2;i++){for(int j=0;j<N2;j++){//曼哈顿距离,此法太妙MDT[i][j]=abs(i/N-j/N)+abs(i%N-j%N);}}puzzle in;for(int i=0;i<N2;i++){cin>>in.f[i];if(in.f[i]==0){in.f[i]=N2;in.space=i;}}string ans=iterative_deepening(in);
// for(int i=0;i<limit;i++){
// cout<<path[i]<<" ";
// }cout<<ans.size()<<endl;return 0;
}
A*
//A*
//优先对“起点到当前位置的成本+当前位置到目标状态的推测值”最小的状态进行状态迁移
#include<bits/stdc++.h>using namespace std;#define N 4
#define N2 16const int dx[4]={0,-1,0,1};
const int dy[4]={1,0,-1,0};
const char dir[4]={'r','u','l','d'};
int MDT[N2][N2];struct Puzzle{int f[N2],space,MD;int cost;bool operator < (const Puzzle &p)const{for(int i=0;i<N2;i++){if(f[i]==p.f[i]){continue;}return f[i]<p.f[i];}return false;}
};struct state{Puzzle puzzle;int estimated;bool operator < (const state &s)const{return estimated>s.estimated;}
};int getALLMD(Puzzle pz)
{int sum=0;for(int i=0;i<N2;i++){if(pz.f[i]==N2){continue;}sum+=MDT[i][pz.f[i]-1];}return sum;
}int astar(Puzzle s)
{priority_queue<state>pq;s.MD=getALLMD(s);s.cost=0;map<Puzzle,bool>V;Puzzle u,v;state initial;initial.puzzle=s;initial.estimated=getALLMD(s);pq.push(initial);while(!pq.empty()){state st=pq.top();pq.pop();u=st.puzzle;if(u.MD==0){return u.cost;}V[u]=true;int sx=u.space/N;int sy=u.space%N;for(int r=0;r<4;r++){int tx=sx+dx[r];int ty=sy+dy[r];if(tx<0||ty<0||tx>=N||ty>=N){continue;}v=u;v.MD-=MDT[tx*N+ty][v.f[tx*N+ty]-1];v.MD+=MDT[sx*N+sy][v.f[tx*N+ty]-1];swap(v.f[sx*N+sy],v.f[tx*N+ty]);v.space=tx*N+ty;if(!V[v]){v.cost++;state news;news.puzzle=v;news.estimated=v.cost+v.MD;pq.push(news);}}}return -1;
}int main()
{for(int i=0;i<N2;i++){for(int j=0;j<N2;j++){MDT[i][j]=abs(i/N-j/N)+abs(i%N-j%N);}}
// for(int i=0;i<N2;i++){
// for(int j=0;j<N2;j++){
// cout<<MDT[i][j]<<" ";
// }
// cout<<endl;
// }Puzzle in;for(int i=0;i<N2;i++){cin>>in.f[i];if(in.f[i]==0){in.f[i]=N2;in.space=i;}}cout<<astar(in)<<endl;return 0;
}
十六宫格拼图(A*/IDA*)(曼哈顿距离)相关推荐
- IDA*算法解十六宫格拼图问题
IDA*算法, ID(Iterative Deepening)指的是迭代加深. 它的思想是重复进行限制最大深度的深度优先搜索(此限制从某个最小值遍历到最大值), 也称为深度受限搜索. 一般情况下, 为 ...
- 汉(海)明码 | “十六宫格法” 破解汉(海)明码相关题目(附软考经典例题)
文章目录 一.前言 二.奇偶校验码 三.海明码概念 四.十六宫格法 1.概述 2.原理 3.填写校验位 4.填写数据位 5.填写十六宫格首位 五.结语 一.前言 很多小伙伴在遇到"汉明码&q ...
- MFC Windows 程序设计[二十五]之五彩十六宫格(附源码)
MFC Windows 程序设计[二十五]之五彩十六宫格 程序之美 前言 主体 运行效果 核心代码 逻辑分析 结束语 程序之美 前言 MFC是微软公司提供的一个类库(class libraries), ...
- MFC Windows 程序设计[三十五]之五彩十六宫格
MFC Windows 程序设计[三十五]之五彩十六宫格 程序之美 前言 主体 运行效果 核心代码 逻辑分析 结束语 程序之美 前言 MFC是微软公司提供的一个类库(class libraries), ...
- 用H5实现四宫格切换九宫格,再切换十六宫格
废话不多说,直接上代码 效果图如下 点击右上角按钮,即可切换4宫格,9宫格,16宫格 html部分 <!-- 切换按钮 --><div class="center" ...
- vue 1 2 3 4 6 9 16宫格 6宫格(六宫格) 9宫格(九宫格) 16宫格(十六宫格) 自定义宫格(样式篇)
直接上图把,如果是你的菜,就点个赞,谢谢. 目录: 我直接在app.vue组件写了.. <template><div class="cell"><di ...
- Python拼图游戏源代码,可定制拼图图片,支持多种难度,可九宫格、十六宫格、二十五宫格
配置环境 安装pygame模块 pip install pygame 引入资源 将照片,添加到resources/pictures路径下 照片.jpg格式 主函数代码 pintu.py 一个配置文件c ...
- 基于canvas+uniapp的9宫格拼图游戏组件
基于 canvas+uniapp 的 9 宫格拼图游戏 涉及到的 canvas 基础知识 创建画布 <canvas id="'c1'"></canvas> ...
- 聚划算霸占淘宝“六宫格”
4月9日,手机淘宝App更名为淘宝App,去掉"手机"前缀表明淘宝移动转型进程已经结束,截止到2018年年底,淘宝移动月度活跃用户比一年前增加1.2亿,达到近7亿.4月16日,淘宝 ...
最新文章
- EOS 智能合约源代码解读 (4)symbol.hpp
- 隐式调用 Intent 大全
- 【渝粤教育】电大中专学前儿童科学教育1作业 题库
- 解释为脑瘫的那张图_Python GIL全局解释器锁详解(深度剖析)
- Python 爬取 620 首虾米歌曲,揭秘五月天为什么狂吸粉?!
- 小学生应该学习编程语言
- NLP数据标注工具调研
- 终端安全防护技术研究(一)
- 【论文翻译 AAAI 2020 | 知识图谱综述】A Survey on Knowledge Graphs: Representation, Acquisition and Applications
- 大数据简介、Hadoop 起源以及 Google 三大论文介绍
- Scroller的使用
- 软件项目管理_作业1
- 常用的RGB值和颜色对照表
- WebSocket原生JavaScript实现简易聊天室
- 苹果股价两月累计跌25% 市值跌破5000亿
- SAP-工艺路线相关的表的关联关系
- Unity_太阳月亮地球的自转公转脚本
- 手推Logistic Regression
- 拼多多按关键词搜索示例
- 电影《一诺千金》剧照首度曝光系列一
热门文章
- 地球物理勘探技术类毕业论文文献有哪些?
- android 修改wifi设备名
- 「积木库」来了,做网站像搭积木一样简单
- 数字图像处理技术及实用 MATLAB实验报告及PS作业
- 用python动态演示照片立方体_3分钟在线演示用 python 生成分形图片
- echarts制作多个纵轴的折线图
- Android平板app开发布局文件,Android平板开发相关
- S3C2440 I2C实现
- idea中摸鱼插件_推荐几款我常用的IDEA插件~网友:妈耶~飞起来咯!
- Hibiscus的脑机接口学习周报(2022/12/26~2022/1/1)