八数码问题求解实验报告讲解Word文档格式.docx
《八数码问题求解实验报告讲解Word文档格式.docx》由会员分享,可在线阅读,更多相关《八数码问题求解实验报告讲解Word文档格式.docx(14页珍藏版)》请在冰豆网上搜索。
我采用了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)所示
图2、宽度优先搜索示意图
2.宽度优先算法如下:
步1把初始结点S0放入OPEN表中步2若OPEN表为空,则搜索失败,问题无解
步3取OPEN表中最前面的结点N放在CLOSE表中,并冠以顺序
编号n
步4若目标结点Sg=N,则搜索成功,问题有解
步5若N无子结点,则转步2
步6扩展结点N,将其所有子结点配上指向N的放回指针,依次
放入OPEN表的尾部,转步2
3.宽度优先算法流程图
图3、宽度优先算法流程图
4.8数码难题用宽度优先搜索所生成的搜索树如图4。
搜索树上的所
有节点都标记它们所对应的状态描述,每个节点旁边的数字表示节点扩展的顺序
(按顺时针方向移动空格)。
图中有26个节点,也就是源程序运行结果。
21
1104So
203
014
184
140
164
705
830
214
883
204
704
615
714
650
123
804
图4.八数码题宽度优先搜索树
五、实验结果及分析
上机试验时,,经多次程序调试,最后得一下结果。
此结果所得节点(状态图)很多,可知宽度优先搜索的盲目性很大,当目标节点距离初始节点较远时,就会产生大量的无用节点,搜索效率低。
但是,只要问题有解,用宽度优先搜索总可以找到它的解。
图5.程序运行结果
六、结论
人工智能搜索可分为盲目搜索和启发式搜索。
盲目搜索算法有宽度优先算法、深度优先算法(有界深度优先算法),启发式搜索算法有A算法、A*算法。
本实验采用的是宽度优先(广度优先)算法,这种算法是按预定的控制策略进行,在搜素的过程中所获得的信息不用来改进控制策略。
由于搜索总是按预定的路线进行,没有考虑问题本身的特性,这种缺乏问题求解的针对性,需要进行全方位的搜索,而没有选择最优的搜索路径。
所以图4宽度优先搜索树及程序运行结果图5得到的节点(状态图)很多,而解路径为1-3-8-16-26,其它节点是没有用的节点,搜索效率很低。
通过这次实验更加熟悉状态空间的宽度优先搜索、深度优先搜索和启发式搜索算法及计算机语言对常用数据结构如链表、队列等的描述应用。
学到了不少知识。
七、源程序及注释
#include<
iostream>
ctime>
vector>
usingnamespacestd;
constintROW=3;
//行数
constintCOL=3;
//列数
constintMAXDISTANCE=10000;
//最多可以有的表的数目
constintMAXNUM=10000;
//Sothecommentfunction=dist+dep.
intindex;
//pointtothelocationofparent
Nodesrc,dest;
//父节表目的表
vector<
Node>
node_v;
//storethenodesboolisEmptyOfOPEN()//open表是否为空
{
for(inti=0;
i<
node_v.size();
i++){
if(node_v[i].dist!
=MAXNUM)
returnfalse;
}
returntrue;
boolisEqual(intindex,intdigit[][COL])//
//distancebetweenonestateandthedestination
一个表和目的表的距离
ROW;
i++)
估价函数值
父节点的位置
存储节点
判断这个最优的节点是否和目的节点一样
for(intj=0;
j<
COL;
j++){
if(node_v[index].digit[i][j]!
=digit[i][j])
ostream&
operator<
<
(ostream&
os,Node&
node)
j++)
os<
node.digit[i][j]<
endl;
returnos;
rstep_v.push_back(node_v[index]);
index=node_v[index].index;
while(index!
=0)
输出每一步的探索过程
for(inti=rstep_v.size()-1;
i>
=0;
i--)//
cout<
"
Step"
<
rstep_v.size()-i
endl<
rstep_v[i]<
voidSwap(int&
a,int&
b)
intt;
t=a;
a=b;
b=t;
voidAssign(Node&
node,intindex)
node.digit[i][j]=node_v[index].digit[i][j];
intGetMinNode()//找到最小的节点的位置即最优节点
intdist=
MAXNUM;
intloc;
//thelocationofminimizenode
for(inti
if(node_v[i].dist==MAXNUM)
continue;
elseif((node_v[i].dist+node_v[i].dep)<
dist){
loc=i;
dist=
node_v[i].dist+node_v[i].dep;
returnloc;
boolisExpandable(Node&
if(isEqual(i,node.digit))
intDistance(Node&
node,intdigit[][COL])
intdistance=0;
boolflag=false;
for(inti=0;
for(intk=0;
k<
k++){
for(intl=0;
l<
l++){
if(node.digit[i][j]==digit[k][l]){
distance+=abs(i-k)+abs(j-l);
flag=true;
break;
else
flag=false;
if(flag)
returndistance;
intMinDistance(inta,intb)
return(a<
b?
a:
b);
voidProcessNode(intindex)
intx,y;
boolflag;
if(node_v[index].digit[i][j]==0)
x=i;
y=j;
flag=true;
elseflag=false;
if(flag)
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);
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);
if(y>
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);
if(y<
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;
Inputsource:
"
i++)//输入初始的表
cin>
>
number;
src.digit[i][j]=number;
src.index=0;
src.dep=1;
Inputdestination:
//输入目的表
for(intm=0;
m<
m++)
for(intn=0;
n<
n++){
dest.digit[m][n]=number;
node_v.push_back(src);
//在容器的尾部加一个数据
Search..."
clock_tstart=clock();
while
(1)
if(isEmptyOfOPEN())
Cann'
tsolvethisstatement!
return-1;
//thelocationoftheminimizenode最优节点的位置
loc=GetMinNode();
if(isEqual(loc,dest.digit))
rstep_v;
Source:
src<
PrintSteps(loc,rstep_v);
Successful!
Using"
(clock()-start)/CLOCKS_PER_SEC
seconds."
ProcessNode(loc);
return0;
十五数码问题的截图(对行和列数进行修改):