八数码问题求解 实验报告讲解.docx
- 文档编号:8158391
- 上传时间:2023-01-29
- 格式:DOCX
- 页数:19
- 大小:118.09KB
八数码问题求解 实验报告讲解.docx
《八数码问题求解 实验报告讲解.docx》由会员分享,可在线阅读,更多相关《八数码问题求解 实验报告讲解.docx(19页珍藏版)》请在冰豆网上搜索。
八数码问题求解实验报告讲解
实验报告
一、实验问题
八数码问题求解
二、实验软件
VC6.0编程语言或其它编程语言
三、实验目的
1.熟悉人工智能系统中的问题求解过程;
2.熟悉状态空间的盲目搜索和启发式搜索算法的应用;
3.熟悉对八数码问题的建模、求解及编程语言的应用。
四、实验数据及步骤
(一、)实验内容
八数码问题:
在3×3的方格棋盘上,摆放着1到8这八个数码,有1个方格是空的,其初始状态如图1所示,要求对空格执行空格左移、空格右移、空格上移和空格下移这四个操作使得棋盘从初始状态到目标状态。
283123
1484
765765
(a)初始状态(b)目标状态
图1八数码问题示意图
(二、)基本数据结构分析和实现
1.结点状态
我采用了structNode数据类型
typedefstruct_Node{
intdigit[ROW][COL];
intdist;//distancebetweenonestateandthedestination一个表和目的表的距离
intdep;//thedepthofnode深度
//Sothecommentfunction=dist+dep.估价函数值
intindex;//pointtothelocationofparent父节点的位置
}Node;2.发生器函数
定义的发生器函数由以下的四种操作组成:
(1)将当前状态的空格上移
Nodenode_up;
Assign(node_up,index);//向上扩展的节点
intdist_up=MAXDISTANCE;
(2)将当前状态的空格下移
Nodenode_down;
Assign(node_down,index);//向下扩展的节点
intdist_down=MAXDISTANCE;
(3)将当前状态的空格左移
Nodenode_left;
Assign(node_left,index);//向左扩展的节点
intdist_left=MAXDISTANCE;
(4)将当前状态的空格右移
Nodenode_right;
Assign(node_right,index);//向右扩展的节点
intdist_right=MAXDISTANCE;
通过定义结点状态和发生器函数,就解决了8数码问题的隐式图的生成问题。
接下来就是搜索了。
3.图的搜索策略
经过分析,8数码问题中可采用的搜速策略共有:
1.广度优先搜索、2.深度优先搜索、2.有界深度优先搜索、4.最好优先搜索、5.局部择优搜索,一共五种。
其中,广度优先搜索法是可采纳的,有界深度优先搜索法是不完备的,最好优先和局部择优搜索法是启发式搜索法。
实验时,采用了广度(宽度)优先搜索来实现。
(三、)广度(宽度)优先搜索原理
1.状态空间盲目搜索——宽度优先搜索
其基本思想是,从初始节点开始,向下逐层对节点进形依次扩展,并考察它是否为目标节点,再对下层节点进行扩展(或搜索)之前,必须完成对当层的所有节点的扩展。
再搜索过程中,未扩展节点表OPEN中的节点排序准则是:
)所示。
1先进入的节点排在前面,后进入的节点排在后面。
其搜索过程如图(.
S
A
B
CFDE
GIH
J
2、宽度优先搜索示意图图
2.宽度优先算法如下:
表中S0放入OPEN步1把初始结点表为空,则搜索失败,问题无解若OPEN步2
表中,并冠以顺序编CLOSEN放在3取OPEN表中最前面的结点步
n
号Sg=N,则搜索成功,问题有解步4若目标结点2
N无子结点,则转步步5若
的放回指针,依次放N扩展结点N,将其所有子结点配上指向步6
2
表的尾部,转步入OPEN3.宽度优先算法流程图
起始
把S放入OPEN表
否是是否OPEN失败?
为空表
表OPE把第一个节n从并把它放CLOSE出
OPEN把它的后继节点放扩n,的指提供回表的末端
否成?
节点为目标节点
、宽度优先算法流程图图3
搜索树上的所有。
数码难题用宽度优先搜索所生成的搜索树如图44.8
节点都标记它们所对应的状态描述,每个节点旁边的数字表示节点扩展的顺序个节点,也就是源程序运行结果。
。
图中有26(按顺时针方向移动空格)
283
1So104
765
283203283283
2345164184140014
765765765705
678910111213
083283023230280283283283
214714184184143145164164
765065765765765760065750
1415161718192021
203283123234208283283283
214714084180143145064160
754
175
706
756
765
765
605
765
2324252226
830883283283123
214204704714804
765765615650765
图4.八数码题宽度优先搜索树
五、实验结果及分析
上机试验时,,经多次程序调试,最后得一下结果。
此结果所得节点(状态图)很多,可知宽度优先搜索的盲目性很大,当目标节点距离初始节点较远时,就会产生大量的无用节点,搜索效率低。
但是,只要问题有解,用宽度优先搜索总可以找到它的解。
图5.程序运行结果
六、结论
人工智能搜索可分为盲目搜索和启发式搜索。
盲目搜索算法有宽度优先算法、深度优先算法(有界深度优先算法),启发式搜索算法有A算法、A*算法。
本实验采用的是宽度优先(广度优先)算法,这种算法是按预定的控制策略进行,在搜素的过程中所获得的信息不用来改进控制策略。
由于搜索总是按预定的路线进行,没有考虑问题本身的特性,这种缺乏问题求解的针对性,需要进行全方位的搜索,而没有选择最优的搜索路径。
所以图4宽度优先搜索树及程序运行结果图5得到的节点(状态图)很多,而解路径为1-3-8-16-26,其它节点是没有用的节点,搜索效率很低。
通过这次实验更加熟悉状态空间的宽度优先搜索、深度优先搜索和启发式搜索算法及计算机语言对常用数据结构如链表、队列等的描述应用。
学到了不少知识。
七、源程序及注释
#include
#include
#include
usingnamespacestd;
constintROW=3;//行数
constintCOL=3;//列数
constintMAXDISTANCE=10000;//最多可以有的表的数目
constintMAXNUM=10000;
typedefstruct_Node{
intdigit[ROW][COL];
intdist;//distancebetweenonestateandthedestination一个表和目的表的距离
intdep;//thedepthofnode深度
//Sothecommentfunction=dist+dep.估价函数值
intindex;//pointtothelocationofparent父节点的位置
}Node;
Nodesrc,dest;//父节表目的表
vector
boolisEmptyOfOPEN()//open表是否为空
{
for(inti=0;i if(node_v[i].dist! =MAXNUM) returnfalse; } returntrue; } boolisEqual(intindex,intdigit[][COL])//判断这个最优的节点是否和目的节点一样 { for(inti=0;i for(intj=0;j if(node_v[index].digit[i][j]! =digit[i][j]) returnfalse; } returntrue; } ostream&operator<<(ostream&os,Node&node) { for(inti=0;i for(intj=0;j os< os< } returnos; } voidPrintSteps(intindex,vector { rstep_v.push_back(node_v[index]); index=node_v[index].index; while(index! =0) { rstep_v.push_back(node_v[index]); index=node_v[index].index; } for(inti=rstep_v.size()-1;i>=0;i--)//输出每一步的探索过程 cout< < } voidSwap(int&a,int&b) { intt; t=a; a=b; b=t; } voidAssign(Node&node,intindex) { for(inti=0;i for(intj=0;j node.digit[i][j]=node_v[index].digit[i][j]; } intGetMinNode()//找到最小的节点的位置即最优节点 { intdist=MAXNUM; intloc;//thelocationofminimizenode for(inti=0;i { if(node_v[i].dist==MAXNUM) continue; elseif((node_v[i].dist+node_v[i].dep) loc=i; dist=node_v[i].dist+node_v[i].dep; } } returnloc; } boolisExpandable(Node&node) { for(inti=0;i if(isEqual(i,node.digit)) returnfalse; } returntrue; } intDistance(Node&node,intdigit[][COL]) { intdistance=0; boolflag=false; for(inti=0;i for(intj=0;j for(intk=0;k for(intl=0;l if(node.digit[i][j]==digit[k][l]){ distance+=abs(i-k)+abs(j-l); flag=true; break; } else flag=false; } if(flag) break; } returndistance; } intMinDistance(inta,intb) { return(a a: b); } voidProcessNode(intindex) { intx,y; boolflag; for(inti=0;i for(intj=0;j if(node_v[index].digit[i][j]==0) { x=i;y=j; flag=true; break; } elseflag=false; } if(flag) break; } Nodenode_up; Assign(node_up,index);//向上扩展的节点 intdist_up=MAXDISTANCE; if(x>0) { Swap(node_up.digit[x][y],node_up.digit[x-1][y]); if(isExpandable(node_up)) { dist_up=Distance(node_up,dest.digit); node_up.index=index; node_up.dist=dist_up; node_up.dep=node_v[index].dep+1; node_v.push_back(node_up); } } Nodenode_down; Assign(node_down,index);//向下扩展的节点 intdist_down=MAXDISTANCE; if(x<2) { Swap(node_down.digit[x][y],node_down.digit[x+1][y]); if(isExpandable(node_down)) { dist_down=Distance(node_down,dest.digit); node_down.index=index; node_down.dist=dist_down; node_down.dep=node_v[index].dep+1; node_v.push_back(node_down); } } Nodenode_left; Assign(node_left,index);//向左扩展的节点 intdist_left=MAXDISTANCE; if(y>0) { Swap(node_left.digit[x][y],node_left.digit[x][y-1]); if(isExpandable(node_left)) { dist_left=Distance(node_left,dest.digit); node_left.index=index; node_left.dist=dist_left; node_left.dep=node_v[index].dep+1; node_v.push_back(node_left); } } Nodenode_right; Assign(node_right,index);//向右扩展的节点 intdist_right=MAXDISTANCE; if(y<2) { Swap(node_right.digit[x][y],node_right.digit[x][y+1]); if(isExpandable(node_right)) { dist_right=Distance(node_right,dest.digit); node_right.index=index; node_right.dist=dist_right; node_right.dep=node_v[index].dep+1; node_v.push_back(node_right); } } node_v[index].dist=MAXNUM; } intmain()//主函数 { intnumber; cout< < for(inti=0;i for(intj=0;j cin>>number; src.digit[i][j]=number; } src.index=0; src.dep=1; cout< < for(intm=0;m for(intn=0;n cin>>number; dest.digit[m][n]=number; } node_v.push_back(src);//在容器的尾部加一个数据 cout< clock_tstart=clock(); while (1) { if(isEmptyOfOPEN()) { cout< < return-1; } else { intloc;//thelocationoftheminimizenode最优节点的位置 loc=GetMinNode(); if(isEqual(loc,dest.digit)) { vector cout< < cout< PrintSteps(loc,rstep_v); cout< < cout< < break; } else ProcessNode(loc); } } return0; } : )对行和列数进行修改(十五数码问题的截图
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 八数码问题求解 实验报告讲解 数码 问题 求解 实验 报告 讲解