接上一篇博客

本文和上一篇博客相关代码下载地址: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. java 声明静态类_java静态类声明--java类可以声明为static吗
  2. [收藏]整理了一些T-SQL技巧
  3. 用Ant编译Flex项目的几点注意事项
  4. hadooprbac_rbac权限管理系统的学习
  5. 信息学奥赛一本通 1982:【19CSPJ普及组】数字游戏
  6. ajax php投票记录功能,PHP+AJAX 投票器功能
  7. 回来不是为了留下,而是为了重新出发 -- 生死阅读影评
  8. iOS学习笔记——多控制器管理
  9. python 操作mysql
  10. python语法学习第五天--lambda表达式、filter()、map()
  11. matlab程序复制出现乱码,matlab程序复制到Word文档里变成乱码,该如何改?
  12. Java 输出三角形
  13. Vue3动态加载图片
  14. 华宇平台负责人_华宇平台负责人
  15. Excel中同一单元格设置不同颜色的字体
  16. vs.net发送邮件(2.0)
  17. selenium + Chrome 滑动验证码破解三之京东 实现某东登录
  18. 计算机组装声卡,计算机组装与维护教程之声卡.pdf
  19. Python爬取图片并保存本地
  20. 秒杀Servlce接口设计

热门文章

  1. Vue3+TS项目中element-plus自动导入组件后,找不到文件
  2. String类的切割功能
  3. 看懂了数智化转型的产业链逻辑,也就看懂了用友BIP
  4. Image Quality Assessment: From Error Visibility to Structural Similarity
  5. 模糊规则、FCM、ANFIS学习笔记(持续更新中......)
  6. 介绍一下Gilde和Picasso以及它们的区别
  7. 验后方差估计python_最大似然估计 (MLE) 最大后验概率(MAP)
  8. 数学 {有界性定理,最值定理,零点定理,介值定理}
  9. mac android usb驱动 win10,如何从Mac OS X创建Windows 10安装程序USB驱动器 | MOS86
  10. [转]研究生能力自我培养手册