资源描述
人工智能基础
大作业
—---八数码难题
学院:数学与计算机科学学院
班级:计科14—1
姓名:王佳乐
学号:12
2016、12、20
一、 实验名称
八数码难题得启发式搜索
二、 实验目得
八数码问题:在3×3得方格棋盘上,摆放着1到8这八个数码,有1个方格就是空得,其初始状态如图1所示,要求对空格执行空格左移、空格右移、空格上移与空格下移这四个操作使得棋盘从初始状态到目标状态.
要求:1、熟悉人工智能系统中得问题求解过程;
2、熟悉状态空间得启发式搜索算法得应用;
3、熟悉对八数码问题得建模、求解及编程语言得应用。
三、 实验设备及软件环境
1. 实验编程工具:VC++ 6、0
2. 实验环境:Windows7 64位
四、 实验方法:启发式搜索
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<stdio、h>
# include<string、h>
# include<malloc、h>
# include〈stdlib、h>
typedef struct node {
ﻩint i,cost,degree,exp,father;
ﻩint a[3][3];
ﻩstruct node *bef,*late;
struct node *son;
}treenode;
int flag=0,count=1,num=0,i=0;
void set(treenode *s);
void cpynode(treenode *s1,treenode *s2);
void add1(treenode *s,treenode *open);
void adjust1(treenode *close);
void jscost(treenode *s);
void tiaozheng(treenode *open);
void sortopen(treenode *open);
int test(treenode *s1,treenode *s2);
void position(treenode *s,treenode *open,treenode *close,treenode *s1);
void printstr(treenode *open);
int search(treenode *s1,treenode *s2);
void input(treenode *s);
int cmpnode(treenode *s1,treenode *s2);
void print(treenode *s);
void add(treenode *s,treenode *close);
void xuhao(treenode *s);
void extend(treenode *r1,treenode *s,treenode *s1,treenode *open,treenode *close);
void main() {
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");}; }
void set(treenode *s) {
s—〉i=i;
s—>father=0;
ﻩs->degree=0;
s—〉bef=NULL;
s->son=NULL;
ﻩs-〉late=NULL; };
void input(treenode *s) {
int j,k;
ﻩfor(j=0;j〈3;j++)
ﻩﻩfor(k=0;k<3;k++)
ﻩﻩ scanf("%d",&s—>a[j][k]); };
int cmpnode(treenode *s1,treenode *s2){
ﻩint j,k;
for(j=0;j<3;j++)
ﻩ for(k=0;k〈3;k++) {
ﻩﻩ if(s1—〉a[j][k]!=s2—>a[j][k])
ﻩ ﻩ return 0; };
ﻩreturn 1; }
int test(treenode *s1,treenode *s2) {
int j,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;
return n; };
void xuhao(treenode *s) {
ﻩi++;
s—〉i=i; }
void cpynode(treenode *s1,treenode *s2) {
ﻩ int j,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; };
void print(treenode *s) {
ﻩint j,k;
ﻩfor(j=0;j<3;j++) {
ﻩ for(k=0;k<3;k++) {
ﻩﻩ printf(”%2d",s->a[j][k]); }
ﻩﻩif(j==1) printf(" n=%2d d=%2d f=%2d”,s—>i,s-〉degree,s-〉father);
printf("\n"); }
ﻩprintf("\n"); }
void position(treenode *s,treenode *open,treenode *close,treenode *s1) {
ﻩint m,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); }; }
void printstr(treenode *s) {
ﻩtreenode *t;
ﻩt=s-〉late;
ﻩwhile(t!=NULL) {
ﻩ num++;
print(t);
ﻩﻩt=t->son; }; }
void extend(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++; }
ﻩ else free(r1); }
else {
ﻩ xuhao(r1);
ﻩﻩﻩjscost(r1);
ﻩ count++;
ﻩ ﻩadd(r1,close);
ﻩﻩr1—〉bef=s;
flag=1; } }
int search(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)
ﻩreturn 0; };
ﻩﻩt=t—>late; };
return 1; }
void add(treenode *s,treenode *close) {
ﻩtreenode *r,*t;
ﻩt=s;
r=close;
ﻩwhile(r—>late!=NULL)
ﻩr=r—>late;
r->late=t;
t—〉late=NULL; }
void add1(treenode *s,treenode *open){
ﻩtreenode *t;
ﻩt=open;
s->late=t->late;
ﻩt-〉late=s; }
void adjust1(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; }; }
void jscost(treenode *s) {
s->cost=(s-〉exp)+s-〉degree; }
void sortopen(treenode *open) {
ﻩtreenode *t,*s,*r;
ﻩint k;
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个新节点。可见,在本实验中启发式搜索更优,效率更高。而在求解最短路径得问题上盲目搜索能更高效一点.在实际得应用中应根据具体情况灵活选择不同得策略,提高程序执行效率
启发式搜索就就是在状态空间中得搜索对每一个搜索得位置进行评估,得到最好得位置,再从这个位置进行搜索直到目标。这样可以省略大量无谓得搜索路径,提高了效率。
七、 结论
此次实验用启发式搜索方法求解问题得使用,让我们明白了具体问题具体分析,更明白了算法得重要,好得算法能够极大得提高程序得运行效率。同时,通过此次实践,也对课本知识有了更深刻得认识与体会,真正将课本知识融于实践中就是对我们得最大考验。
这次试验让我更加深入了解了什么就是人工智能,让我了解了人工智能得作用以及含义与人工智能得使用范围以及对于我们未来生活得作用得广大.用机器语言解决实际问题得,提高了动手能力。
展开阅读全文