人工智能基础大作业—---八数码难题学院:数学与计算机科学学院班级:计科14—1姓名:王佳乐学号:122016、12、20一、实验名称八数码难题得启发式搜索二、实验目得八数码问题:在3×3得方格棋盘上,摆放着1到8这八个数码,有1个方格就是空得,其初始状态如图1所示,要求对空格执行空格左移、空格右移、空格上移与空格下移这四个操作使得棋盘从初始状态到目标状态.要求:1、熟悉人工智能系统中得问题求解过程;2、熟悉状态空间得启发式搜索算法得应用;3、熟悉对八数码问题得建模、求解及编程语言得应用。
三、实验设备及软件环境1.实验编程工具:VC++ 6、02.实验环境: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);voidtiaozheng(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);intsearch(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,treenod e *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(treenod e));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) {ﻩ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; };ﻩreturn1; }inttest(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){ﻩ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=%2df=%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;}}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;};return 1; }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;}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;ﻩ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、搜索过程请输入八数码得初始状态:(以空格为分隔)ﻫ28 31 0 47 65请输入八数码得目标状态:(以空格为分隔)1 2 38 0 47 65ﻫ搜索过程如下:ﻫ 2 83ﻫ14n= 1 d= 0 f7ﻫ56=0ﻫ2 0 3ﻫ 1 8 4n=3d= 1 f=17 6 5ﻫ0 2 31 8 4 n= 8 d= 2f=37 657561 2 3ﻫ08 4 n=10 d= 3 f= 8ﻫ12 3804n=12d= 4 f=10765ﻫﻫ5 步,12 个节点ﻫPress any key to continue六、实验分析:在进行搜索得过程中,同时记录了扩展新节点得个数。