博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
八数码问题_启发搜索
阅读量:5759 次
发布时间:2019-06-18

本文共 5712 字,大约阅读时间需要 19 分钟。

#include
#include
typedef struct { long parent; long index; int direction;//记录上一节点到当前节点空格移动方向 int Grid[9];//存储局面 int H;//启发函数值}State;State S,T;//起始态,目标态(目标态由评估函数决定好了)State OPEN[2048];//队列-----待考察的状态State CLOSE[2048];//--------考察过的状态int OPhead=0,OPtail=0,openlen=2048;int CLhead=0,CLtail=0,closelen=2048;long INDEX=0;//记录下标void readdata();int search();int Evaluate(State s);State Swap(State v,int Epindex,int Nindex);//交换两个位置上的值int Judge(State father,int n,int BlankIndex,int NumIndex);void AI_Inspire();void addtoopen(State v);//将节点v加到队列尾State takeoutofopen();//取队列头数据void addtoclose(State v);int main(){ readdata();//读取起始状态 int flag=search(); int kk; if(flag==1)//找到了,输出CLOSE表中的考察过的状态 { for(kk=CLhead;kk
=CLhead;i--) { if(End.parent ==CLOSE[i].index) { Process[k++]=CLOSE[i]; End=CLOSE[i]; } } for(j=k-1;j>=0;j--)//输出从起点到终点的局面变化过程 { printf("第%d个状态: ",k-1-j); for(int jj=0;jj<9;jj++) printf(" %d",Process[j].Grid[jj]); printf("\n"); }*/ } else printf("未找到\n"); return 0;}int search(){ State father; while(OPhead != OPtail)//OPEN[]表中还有待考察的数据 { int BlankIndex,NumIndex; father = takeoutofopen();//从队列头取数据 addtoclose(father);//将father节点加入CLOSE表(已考察) for(int k=0;k<9;k++) if(father.Grid[k]==0) { BlankIndex=k; break; } //记录父节点father空格位所在的位置 //四个方向搜索// //空格向左移 if(father.direction !=3) { NumIndex=BlankIndex/3*3+BlankIndex%3-1; if(BlankIndex%3-1>=0) { int flag=Judge(father,1,BlankIndex,NumIndex); if(flag==1) return 1; } } //空格向上移 if(father.direction !=4) { NumIndex=(BlankIndex/3-1)*3+BlankIndex%3;//计算待移动的数据所在的位置 if(BlankIndex/3-1>=0) { int flag=Judge(father,2,BlankIndex,NumIndex); if(flag==1) return 1; } } //空格向右移 if(father.direction !=1) { NumIndex=BlankIndex/3*3+BlankIndex%3+1; if(BlankIndex%3+1<3) { int flag=Judge(father,3,BlankIndex,NumIndex); if(flag==1) return 1; } } //空格向下移 if(father.direction !=2) { NumIndex=(BlankIndex/3+1)*3+BlankIndex%3; if(BlankIndex/3+1<3) { int flag=Judge(father,4,BlankIndex,NumIndex); if(flag==1) return 1; } } AI_Inspire();//调整OPEN标 } return 0;}void AI_Inspire(){ //按启发函数值对OPEN表中的元素进行排序----降序 State temp[2048]; int t=0; int ii,jj; //取出 if(OPtail
= temp[kk].H) //正确位码的个数大的放在队列的最前面,优先展开 kk=jj; State tp=temp[ii]; temp[ii]=temp[kk]; temp[kk]=tp; } //printf("%d---",temp[0].H);//调试 //放回 t=0; if(OPtail
son son.H=Evaluate(son);//4.子节点的启发函数值 if(son.H==T.H) { son.index =INDEX++; addtoclose(son); return 1; //表明找到了终点 } else { son.index =INDEX++; //2.子节点自己的下标---father.index*4+n以指数形式增长,会超出long的范围(不能用) addtoopen(son);//将当前状态节点加入到OPEN表 } return 0;}void addtoopen(State v){ OPEN[OPtail++]=v; //向尾部添加节点 OPtail = OPtail%openlen;}State takeoutofopen()//从队列头取节点数据{ State v; v=OPEN[OPhead++];//向头部取节点 OPhead=OPhead%openlen; return v;}void addtoclose(State v){ CLOSE[CLtail++]=v; CLtail = CLtail%closelen;}//v为传入的局面,BlankIndex为空格位置,NumIndex为被交换的数据位置State Swap(State son,int BlankIndex,int NumIndex){ int temp=son.Grid[BlankIndex];//取空格位置的数字 son.Grid[BlankIndex]=son.Grid[NumIndex]; son.Grid[NumIndex]=temp; return son;//返回新局面}int Evaluate(State s)//启发式函数{ int count=0;//正确位码的个数 for(int i=0;i<9;i++) { if(s.Grid[i]==T.Grid[i] && s.Grid[i]!=0) count++; } return count;//返回逆序值}void readdata(){ int Arr[10]={
8,7,6,5,4,3,2,1,0}; int Brr[10]={
0,1,2,3,4,5,6,7,8}; //28步 //终止局面 T.index=-1;//1 T.parent=-1;//2 for(int i=0;i<9;i++)//4 T.Grid[i]=Arr[i]; T.H=Evaluate(T);//5 //起始局面 S.index=INDEX++; S.parent=-1; for(i=0;i<9;i++) S.Grid[i]=Brr[i]; S.H=Evaluate(S);//起始局面评估 addtoopen(S); }

测例:

第0个状态:  0 1 2 3 4 5 6 7 8    节点扩展下标: 0

第1个状态:  3 1 2 0 4 5 6 7 8    节点扩展下标: 2
第2个状态:  3 1 2 6 4 5 0 7 8    节点扩展下标: 4
第3个状态:  3 1 2 6 4 5 7 0 8    节点扩展下标: 5
第4个状态:  3 1 2 6 4 5 7 8 0    节点扩展下标: 7
第5个状态:  3 1 2 6 4 0 7 8 5    节点扩展下标: 8
第6个状态:  3 1 0 6 4 2 7 8 5    节点扩展下标: 10
第7个状态:  3 0 1 6 4 2 7 8 5    节点扩展下标: 11
第8个状态:  0 3 1 6 4 2 7 8 5    节点扩展下标: 12
第9个状态:  6 3 1 0 4 2 7 8 5    节点扩展下标: 14
第10个状态:  6 3 1 7 4 2 0 8 5    节点扩展下标: 16
第11个状态:  6 3 1 7 4 2 8 0 5    节点扩展下标: 17
第12个状态:  6 3 1 7 4 2 8 5 0    节点扩展下标: 19
第13个状态:  6 3 1 7 4 0 8 5 2    节点扩展下标: 20
第14个状态:  6 3 0 7 4 1 8 5 2    节点扩展下标: 22
第15个状态:  6 0 3 7 4 1 8 5 2    节点扩展下标: 23
第16个状态:  0 6 3 7 4 1 8 5 2    节点扩展下标: 24
第17个状态:  7 6 3 0 4 1 8 5 2    节点扩展下标: 26
第18个状态:  7 6 3 8 4 1 0 5 2    节点扩展下标: 28
第19个状态:  7 6 3 8 4 1 5 0 2    节点扩展下标: 29
第20个状态:  7 6 3 8 4 1 5 2 0    节点扩展下标: 31
第21个状态:  7 6 3 8 4 0 5 2 1    节点扩展下标: 32
第22个状态:  7 6 0 8 4 3 5 2 1    节点扩展下标: 34
第23个状态:  7 0 6 8 4 3 5 2 1    节点扩展下标: 35
第24个状态:  0 7 6 8 4 3 5 2 1    节点扩展下标: 36
第25个状态:  8 7 6 0 4 3 5 2 1    节点扩展下标: 38
第26个状态:  8 7 6 5 4 3 0 2 1    节点扩展下标: 40
第27个状态:  8 7 6 5 4 3 2 0 1    节点扩展下标: 41
第28个状态:  8 7 6 5 4 3 2 1 0    节点扩展下标: 43

转载于:https://www.cnblogs.com/IThaitian/archive/2012/10/16/2726549.html

你可能感兴趣的文章
Oracle将NetBeans交给了Apache基金会
查看>>
填坑记:Uncaught RangeError: Maximum call stack size exceeded
查看>>
SpringCloud之消息总线(Spring Cloud Bus)(八)
查看>>
DLA实现跨地域、跨实例的多AnalyticDB读写访问
查看>>
基于Hyperledger Fabric交易系统帐户的钱包模型的java Chaincode实例
查看>>
实时编辑
查看>>
北漂之毕业裁员后的又一波奇遇
查看>>
Python数据分析:pandas常用函数
查看>>
KVO原理分析及使用进阶
查看>>
JSP第五篇【JSTL的介绍、core标签库、fn方法库、fmt标签库】
查看>>
Vue系列(四):模块化开发、Elment UI、自定义全局组件(插件)、Vuex
查看>>
【348天】每日项目总结系列086(2018.01.19)
查看>>
extjs-mvc结构实践(五):实现用户管理的增删改查
查看>>
【JS基础】初谈JS现有的数据类型
查看>>
【294天】我爱刷题系列053(2017.11.26)
查看>>
Microsoft发布了Azure Bot Service和LUIS的GA版
查看>>
Google发布Puppeteer 1.0
查看>>
何时该用无服务器,何时该用Kubernetes?
查看>>
窗口进度条及其高级使用
查看>>
实录分享&视频 | 微软Visual Studio Code是这样支持Docker的
查看>>