人工智能八数码难题的启发式搜索.docx
《人工智能八数码难题的启发式搜索.docx》由会员分享,可在线阅读,更多相关《人工智能八数码难题的启发式搜索.docx(14页珍藏版)》请在冰豆网上搜索。
人工智能八数码难题的启发式搜索
人工智能基础
大作业
----八数码难题
学院:
数学与计算机科学学院
2016.12.20
一、实验名称
八数码难题的启发式搜索
二、实验目的
八数码问题:
在3×3的方格棋盘上,摆放着1到8这八个数码,有1个方格是空的,其初始状态如图1所示,要求对空格执行空格左移、空格右移、空格上移和空格下移这四个操作使得棋盘从初始状态到目标状态。
要求:
1.熟悉人工智能系统中的问题求解过程;
2.熟悉状态空间的启发式搜索算法的应用;
3.熟悉对八数码问题的建模、求解及编程语言的应用。
三、实验设备及软件环境
1.实验编程工具:
VC++6.0
2.实验环境:
Windows764位
四、实验方法:
启发式搜索
1.算法描述
1.将S放入open表,计算估价函数f(s)
2.判断open表是否为空,若为空则搜索失败,否则,将open表中的第一个元素加入close表并对其进行扩展(每次扩展后加入open表中的元素按照代价的大小从小到大排序,找到代价最小的节点进行扩展)
注:
代价的计算公式f(n)=d(n)+w(n).其中f(n)为总代价,d(n)为节点的度,w(n)用来计算节点中错放棋子的个数。
判断i是否为目标节点,是则成功,否则拓展i,计算后续节点f(j),利用f(j)对open表重新排序
2.算法流程图:
3.程序源代码:
#include
#include
#include
#include
typedefstructnode{
inti,cost,degree,exp,father;
inta[3][3];
structnode*bef,*late;
structnode*son;
}treenode;
intflag=0,count=1,num=0,i=0;
voidset(treenode*s);
voidcpynode(treenode*s1,treenode*s2);
voidadd1(treenode*s,treenode*open);
voidadjust1(treenode*close);
voidjscost(treenode*s);
voidtiaozheng(treenode*open);
voidsortopen(treenode*open);
inttest(treenode*s1,treenode*s2);
voidposition(treenode*s,treenode*open,treenode*close,treenode*s1);
voidprintstr(treenode*open);
intsearch(treenode*s1,treenode*s2);
voidinput(treenode*s);
intcmpnode(treenode*s1,treenode*s2);
voidprint(treenode*s);
voidadd(treenode*s,treenode*close);
voidxuhao(treenode*s);
voidextend(treenode*r1,treenode*s,treenode*s1,treenode*open,treenode*close);
voidmain(){
treenode*s0,*s1,*s;
treenode*open,*close,*opend,*closed;
open=(treenode*)malloc(sizeof(treenode));
close=(treenode*)malloc(sizeof(treenode));
open->late=NULL;
close->late=NULL;
opend=open;
closed=close;
s0=(treenode*)malloc(sizeof(treenode));
set(s0);
s1=(treenode*)malloc(sizeof(treenode));
set(s1);
printf("请输入八数码的初始状态:
(以空格为分隔)\n");
input(s0);
printf("请输入八数码的目标状态:
(以空格为分隔)\n");
input(s1);
xuhao(s0);
add(s0,opend);
while(open->late!
=NULL&&flag==0){
s=(treenode*)malloc(sizeof(treenode));
cpynode(s,open->late);
open=open->late;
add(s,close);
if(test(s,s1)==0){
flag=1;}
else{
position(s,open,close,s1);
sortopen(open);};};
if(open->late!
=NULL){
printf("搜索过程如下:
\n");
adjust1(close);
printstr(close);
printf("\n%d步,%d个节点\n",num,count);}
else{
printf("查找错误!
\n");};}
voidset(treenode*s){
s->i=i;
s->father=0;
s->degree=0;
s->bef=NULL;
s->son=NULL;
s->late=NULL;};
voidinput(treenode*s){
intj,k;
for(j=0;j<3;j++)
for(k=0;k<3;k++)
scanf("%d",&s->a[j][k]);};
intcmpnode(treenode*s1,treenode*s2){
intj,k;
for(j=0;j<3;j++)
for(k=0;k<3;k++){
if(s1->a[j][k]!
=s2->a[j][k])
return0;};
return1;}
inttest(treenode*s1,treenode*s2){
intj,k,n=0;
for(j=0;j<3;j++)
for(k=0;k<3;k++){
if(s1->a[j][k]!
=s2->a[j][k])
n++;};
s1->exp=n;
returnn;};
voidxuhao(treenode*s){
i++;
s->i=i;}
voidcpynode(treenode*s1,treenode*s2){
intj,k;
for(j=0;j<3;j++)
for(k=0;k<3;k++)
s1->a[j][k]=s2->a[j][k];
s1->bef=s2->bef;
s1->cost=s2->cost;
s1->exp=s2->exp;
s1->degree=s2->degree;
s1->i=s2->i;
s1->father=s2->father;};
voidprint(treenode*s){
intj,k;
for(j=0;j<3;j++){
for(k=0;k<3;k++){
printf("%2d",s->a[j][k]);}
if(j==1)printf("n=%2dd=%2df=%2d",s->i,s->degree,s->father);
printf("\n");}
printf("\n");}
voidposition(treenode*s,treenode*open,treenode*close,treenode*s1){
intm,n,t,k;
treenode*r1;
for(m=0;m<3;m++){
for(n=0;n<3;n++){
k=s->a[m][n];
if(k==0)
break;};
if(k==0)break;}
if(m+1<=2&&flag==0){
r1=(treenode*)malloc(sizeof(treenode));
cpynode(r1,s);
t=r1->a[m+1][n];
r1->a[m+1][n]=r1->a[m][n];
r1->a[m][n]=t;
extend(r1,s,s1,open,close);};
if(m-1>=0&&flag==0){
r1=(treenode*)malloc(sizeof(treenode));
cpynode(r1,s);
t=r1->a[m-1][n];
r1->a[m-1][n]=r1->a[m][n];
r1->a[m][n]=t;
extend(r1,s,s1,open,close);};
if(n-1>=0&&flag==0){
r1=(treenode*)malloc(sizeof(treenode));
cpynode(r1,s);
t=r1->a[m][n-1];
r1->a[m][n-1]=r1->a[m][n];
r1->a[m][n]=t;
extend(r1,s,s1,open,close);};
if(n+1<=2&&flag==0){
r1=(treenode*)malloc(sizeof(treenode));
cpynode(r1,s);
t=r1->a[m][n+1];
r1->a[m][n+1]=r1->a[m][n];
r1->a[m][n]=t;
extend(r1,s,s1,open,close);};}
voidprintstr(treenode*s){
treenode*t;
t=s->late;
while(t!
=NULL){
num++;
print(t);
t=t->son;};}
voidextend(treenode*r1,treenode*s,treenode*s1,treenode*open,treenode*close){
r1->father=s->i;
r1->degree=s->degree+1;
if(test(r1,s1)!
=0){
jscost(r1);
if(search(r1,close)==1&&search(r1,open)==1){
xuhao(r1);
add1(r1,open);
r1->bef=s;
count++;}
elsefree(r1);}
else{
xuhao(r1);
jscost(r1);
count++;
add(r1,close);
r1->bef=s;
flag=1;}}
intsearch(treenode*s1,treenode*close){
treenode*r,*t;
r=s1;
t=close->late;
while(t!
=NULL){
if(r->exp==t->exp){
if(cmpnode(r,t)==1)
return0;};
t=t->late;};
return1;}
voidadd(treenode*s,treenode*close){
treenode*r,*t;
t=s;
r=close;
while(r->late!
=NULL)
r=r->late;
r->late=t;
t->late=NULL;}
voidadd1(treenode*s,treenode*open){
treenode*t;
t=open;
s->late=t->late;
t->late=s;}
voidadjust1(treenode*close){
treenode*s,*t;
s=close;
s->late->bef=NULL;
while(s->late!
=NULL)
s=s->late;
s->son=NULL;
while(s->bef!
=NULL){
t=s->bef;
t->son=s;
s=s->bef;};}
voidjscost(treenode*s){
s->cost=(s->exp)+s->degree;}
voidsortopen(treenode*open){
treenode*t,*s,*r;
intk;
r=(treenode*)malloc(sizeof(treenode));
t=open->late;
while(t!
=NULL&&t->late!
=NULL){
s=t->late;
k=t->cost;
while(s!
=NULL){
if(k>s->cost){
k=s->cost;
cpynode(r,t);
cpynode(t,s);
cpynode(s,r);}
s=s->late;}
t=t->late;};}
五、实验结果:
1.程序截图
2.搜索过程
请输入八数码的初始状态:
(以空格为分隔)
2 8 3
1 0 4
7 6 5
请输入八数码的目标状态 :
(以空格为分隔)
1 2 3
8 0 4
7 6 5
搜索过程如下:
2 8 3
1 0 4 n= 1 d= 0 f= 0
7 6 5
2 0 3
1 8 4 n= 3 d= 1 f= 1
7 6 5
0 2 3
1 8 4 n= 8 d= 2 f= 3
7 6 5
1 2 3
0 8 4 n=10 d= 3 f= 8
7 6 5
1 2 3
8 0 4 n=12 d= 4 f=10
7 6 5
5 步,12 个节点
Press any key to continue
六、实验分析:
在进行搜索的过程中,同时记录了扩展新节点的个数。
启发式搜索仅扩展12个新节点。
可见,在本实验中启发式搜索更优,效率更高。
而在求解最短路径的问题上盲目搜索能更高效一点。
在实际的应用中应根据具体情况灵活选择不同的策略,提高程序执行效率
启发式搜索就是在状态空间中的搜索对每一个搜索的位置进行评估,得到最好的位置,再从这个位置进行搜索直到目标。
这样可以省略大量无谓的搜索路径,提高了效率。
七、结论
此次实验用启发式搜索方法求解问题的使用,让我们明白了具体问题具体分析,更明白了算法的重要,好的算法能够极大的提高程序的运行效率。
同时,通过此次实践,也对课本知识有了更深刻的认识和体会,真正将课本知识融于实践中是对我们的最大考验。
这次试验让我更加深入了解了什么是人工智能,让我了解了人工智能的作用以及含义和人工智能的使用范围以及对于我们未来生活得作用的广大。
用机器语言解决实际问题的,提高了动手能力。