接上一篇博客

本文和上一篇博客相关代码下载地址:http://download.csdn.net/detail/realmagician/6748915

生成可解的智能拼图后(具体方法参见: http://blog.csdn.net/realmagician/article/details/17395035)就要想办法找到自动解决的办法。

对于3*3的拼图游戏,有9!种排列方式,其中有一半是可解的。
首先可以暴力搜索,采用dfs的策略,每次大概需要10W次移动,这是不可接受的。。
再就是用A*算法的思想解决。A*算法类似BFS,都是用一个数据结构保存可能的路径,在BFS中用队列,A*中用openList(可以用堆实现)。然后从数据结构中选一个当前代价(拼图中就是移动次数)最少的节点继续搜索。在设置一个数据结构表示已访问过的状态。
BFS只考虑了从起点到当前搜索点的代价。而A*算法是基于估计的,即当前代价由起点到当前搜索点的代价与当前搜索点到目标点的估计代价之和表示,用公式可以表示为:f(n)=C(n)+G(n)。
估计代价是A*的关键之处。我的想法是计算当前状态和目标状态的差异,设当前状态可以用矩阵A[3][3]表示,目标状态可以用矩阵B[3][3]表示。找到A[ai][aj]在B中的对应点B[bi][bj],那么这两个点的距离可以用欧式距离表示dis = sqrt((ai-bi)^2+(aj-bj)^2)。那么估计代价就是两个矩阵中所有点的距离之和G(n) = SUM(dis)。
具体编码的时候用一个双向链表表示openList,但是pre指针不是指向前一个节点,而是指向上一个状态的节点。
class ptstate{
public:int currentCost;//当前实际代价int guessCost;//当前实际代价估计代价int state;ptstate( int _currentCost=0,int _guessCost=0,int _state=0):currentCost(_currentCost),guessCost(_guessCost),state(_state){};ptstate(ptstate &_ptstate){currentCost = _ptstate.currentCost;guessCost = _ptstate.guessCost;state = _ptstate.state;}void setState(int _currentCost,int _guessCost, int _state){currentCost = _currentCost;guessCost = _guessCost;state = _state;}
};
typedef struct openListEle{ptstate pts;openListEle *next;openListEle *pre; //指向上一个状态,而非上一个节点void addNext(openListEle *ole){if(ole == NULL)return;ole->next = this->next;this->next = ole;ole->pre = this;}
}openListEle;

A*算法的主要步骤:
为了方便,我把拼图的矩阵用一个整数表示,用一个set<int>保存已访问过的节点。
void pingtuAstar(int pt[vol][col],int correct[vol][col]){visited.clear();//判断是否是正确状态int correctStateInt = makeInt(correct);if(correctStateInt == makeInt(pt)){cout<< "已是正确状态" <<endl;return;}//初始化头节点openListEle *openList = new openListEle;openList->next = NULL;openList->pre = NULL;//将初始状态加入openlistopenListEle *startEle = new openListEle;startEle->pts.setState(0,0,makeInt(pt));openList->addNext(startEle);openListEle *finalEle = new openListEle;finalEle = NULL;while(true ){if(finalEle != NULL)break;//找到openlist中代价最小的openListEle *minEleP = openList->next;openListEle *minEle = NULL;int minCost = -1;int minElePCount = 0;while(minEleP!=NULL){if(minCost == -1 || minEleP->pts.guessCost<minCost){minCost = minEleP->pts.guessCost;minEle = minEleP;}minElePCount++;minEleP = minEleP->next;}if(minEle == NULL || minEle->pre == NULL)break;//计算以当前状态的可变状态的guessCostint tmpPt[vol][col];int data = minEle->pts.state;for(int i=vol-1;i>=0;--i){for(int j=col-1;j>=0;--j){tmpPt[i][j] = data%10;data = data/10;}}int zi = 0,zj = 0;for(int i=0;i<vol;++i){for(int j=0;j<col;++j)if(tmpPt[i][j] == vol*col-1){zi = i;zj = j;break;}}int offseti[4] = {-1,0,1,0};int offsetj[4] = {0,1,0,-1};for(int i=0;i<4;++i){int ti = zi+offseti[i];int tj = zj+offsetj[i];if(ti<0 || ti>vol-1 || tj<0 || tj>col-1)continue;int t = tmpPt[ti][tj];tmpPt[ti][tj] = tmpPt[zi][zj];tmpPt[zi][zj] = t;int hashcode = makeInt(tmpPt);if(visited.find(hashcode) == visited.end()){visited.insert(hashcode);openListEle *newEle = new openListEle;int tmpguessCost = getGuessCostBetweenTwoState(tmpPt,correct);newEle->pts = ptstate(minEle->pts.currentCost+1,minEle->pts.currentCost+1+tmpguessCost,hashcode);minEle->addNext(newEle);if(hashcode == correctStateInt)finalEle = newEle;}t = tmpPt[ti][tj];tmpPt[ti][tj] = tmpPt[zi][zj];tmpPt[zi][zj] = t;}//从openList中删除deleteOpenListEle(openList,minEle);}                //保存路径stack<openListEle*> rightpath;openListEle *pathEle = finalEle;while(pathEle != NULL){rightpath.push(pathEle);                    pathEle = pathEle->pre;}int steps = 0;//输出路径while(!rightpath.empty()){pathEle = rightpath.top();printPingTu(pathEle->pts.state);getchar();steps++;rightpath.pop();                    }cout<< "共需:"<<steps<<"步" <<endl;
}
一些辅助代码:
set<int> visited;
long long makeInt(int a[vol][col]){   long long sum = 0;for(int i=0;i<vol;++i)for(int j=0;j<col;++j){sum = 10*sum+a[i][j];                                          }return sum;
}int getGuessCostBetweenTwoState(int a[vol][col],int b[vol][col]){int guessCost = 0;for(int ai=0;ai<vol;++ai)for(int aj=0;aj<col;++aj){bool found = false ;for(int bi=0;bi<vol && found == false;++bi)for(int bj=0;bj<col && found == false;++bj)if(a[ai][aj] == b[bi][bj]){guessCost += sqrt(1.0*(ai-bi)*(ai-bi)+(aj-bj)*(aj-bj));found = true;}}return guessCost;
}

运行截图如下:

自动解决智能拼图,A*算法相关推荐

  1. java拼图自动还原算法_自动解决智能拼图,A*算法+生成可解拼图(C++)

    [实例简介] 自动生成可解拼图问题,并用A*算法给出自动完成的步骤..另外还有暴力搜索的代码 [实例截图] [核心代码] pingtukejie └── pingtukejie ├── Release ...

  2. matlab 排课,Matlab 遗传算法解决智能排课算法 一天四节课,上午两节,下午两

    Matlab 遗传算法解决智能排课算法 一天四节课,上午两节,下午两 Matlab 遗传算法解决智能排课算法 一天四节课,上午两节,下午两节,同一门课不能相邻,特殊课程不能相邻(语文和英语,数学和科学 ...

  3. 回溯算法解决智能拼图的最小步骤的问题

    文章目录 题目描述 分析 代码的完整实现 题目描述 要求输入一个拼图的初始状态,返回拼图的成功所经过的最小的步数,例如: 初始状态: 1 2 3 4 5 6 7 0 8 成功的状态 1 2 3 4 5 ...

  4. Matlab 遗传算法解决智能排课算法 一天四节课,上午两节,下午两节,同一门课不能相邻,特殊课程不能相邻(语文和英语,数学和科学),求可行方案?

    1.要排课的课程有9门,分别给与编码1,2,3,4,5,6,7,8,9.对应的一周上课次数如下所示: 课程名 编码 一周上几次 Chinese 1 3 English 2 3 Math 3 3 Sci ...

  5. Python爬虫拓展应用:最新版本问卷星自动刷,包括解决智能验证、滑块等问题

    Python爬虫拓展应用: 最新版本问卷星自动刷,包括:解决智能验证.滑块等问题 Python爬虫自动刷"问卷星"网站问卷 爬虫运行准备 爬虫运行代码 代码解释 参考博客 Pyth ...

  6. 基于 Flink ML 搭建的智能运维算法服务及应用

    摘要:本文整理自阿里云计算平台算法专家张颖莹,在 Flink Forward Asia 2022 AI 特征工程专场的分享.本篇内容主要分为五个部分: 阿里云大数据平台的智能运维 智能运维算法服务应用 ...

  7. ccf 智能运维 裴丹_裴丹:智能运维算法需要工业界

    裴丹:智能运维算法需要工业界 学术界密切合作实现技术突破 ■商灏 清华的计算机系,国内一流,而其智能运维研究,据业内人士透露,近两年已超越美国同行,为世界最顶尖水平.本篇可能是国内财经媒体首次触及此类 ...

  8. AlphaGo之父哈萨比斯: 先解决智能 再用智能解决一切

    AlphaGo之父哈萨比斯: 先解决智能 再用智能解决一切 2017年06月01日 06:56 第一财经日报 33微博微信空间分享添加喜爱 刘佳 ["我的背景很多元化.不要循规蹈矩,走自己的 ...

  9. 自动(智能)驾驶系列|(一)简介与传感器

    说明:本系列为自动(智能驾驶)感知融合的技术栈和思路(部分图片和资料来源于网络) 本专题是将自己学到的内容整理复习一下,并分享给想学习这方面的人.这是此系列的第一篇文章,主要是介绍,后面也会更算法理解 ...

最新文章

  1. MDL--元数据锁的锁请求与锁等待+元数据锁类对象
  2. B计划 第四周(开学第一周)
  3. 查看CentOS的系统版本(亲测)
  4. CSS中的块元素,内联元素,内联块元素
  5. JMeter如何切换成中文详细步骤
  6. 企业巧妙运用飞秋提高工作效率
  7. Java中构造方法的执行顺序
  8. performSelector:withObject:afterDelay: 精要概览(持续更新)
  9. 回车(carriage return)和换行(line feed)的区别和来历
  10. C语言 二进制文件读写实例讲解
  11. c语言ax2bxc0的求根公式,ax2+bx+c=0的求根公式
  12. NFT Insider #58:麦当娜和 Beeple 推出 NFT,YGG 与 Magic Eden 达成合作
  13. sentence_transformers 微调模型
  14. 【计算广告】浅谈广告归因
  15. Nginx实现高可用
  16. ux设计_我是一名开发人员,正在过渡到UX设计帮助
  17. 计算机一级程测试题,2017计算机全国一级考试选择题整理.doc
  18. 如何为firefox安装视频播放器
  19. html 气泡上升效果,css气泡效果
  20. IPv6技术精要(第2版)Rick Graziani

热门文章

  1. 将Yolo格式标注文件转换为VOC格式
  2. 命令行 按表模糊查询导出orecal数据库
  3. eclipse+gcc STM32开发环境搭建及调试
  4. Linux添加http服务失败,Apache Web服务器配置http2各种失败
  5. pillow属于python标准库吗_详解Python图像处理库Pillow常用使用方法
  6. html5标准新特性及其使用技巧
  7. 通用嵌入式系统软件测试平台的设计
  8. 实现html和word的相互转换(带图片)
  9. PyQt5 控件学习(一个一个学习之QObject)
  10. 51系列单片机指令快速记忆法