631306050121吴文静+启发式搜索+状态空间搜索_第1页
631306050121吴文静+启发式搜索+状态空间搜索_第2页
631306050121吴文静+启发式搜索+状态空间搜索_第3页
631306050121吴文静+启发式搜索+状态空间搜索_第4页
631306050121吴文静+启发式搜索+状态空间搜索_第5页
已阅读5页,还剩8页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

重庆交通大学计算机与信息学院验证性实验报告班级:软件开发专业2013级1班学号:631306050121姓名:吴文静实验项目名称:启发式搜索实验项目性质:验证性实验实验所属课程:人工智能实验室(中心):软件中心实验室(语音楼8楼)指导教师:朱振国实验完成时间:2016年6月12日评阅意见:签名:年月曰理解和掌握A*算法。二、实验内容及要求内容:在8数码问题中,利用策略函数判断搜索,并使用A*算法减少搜索目标。要求:用选定的编程语言编写程序,利用不同的搜索策略进行状态空间搜索(如宽度优先搜索、深度优先搜索、有界深度优先搜索等)。三、实验设备及软件PC机一台VC6.0编程语言或其它编程语言四、设计方案㈠题目《启发式搜索》㈡设计的主要思路八数码问题的求解算法(1)盲目搜索宽度优先搜索算法、深度优先搜索算法(2)启发式搜索启发式搜索算法的基本思想是:定义一个评价函数f,对当前的搜索状态进行评估,找出一个最有希望的节点来扩展。先定义下面几个函数的含义:f*(n)=g*(n)+h*(n)(1)式中g*(n)表示从初始节点s到当前节点n的最短路径的耗散值;h*(n)表示从当前节点n到目标节点g的最短路径的耗散值,f*(n)表示从初始节点s经过n到目标节点g的最短路径的耗散值。评价函数的形式可定义如(2)式所示:f(n)=g(n)+h(n)(2)其中n是被评价的当前节点°f(n)、g(n)和h(n)分别表示是对f*(n)、g*(n)和h*(n)3个函数值的估计值。利用评价函数f(n)=g(n)+h(n)来排列OPEN表节点顺序的图搜索算法称为算法A。在A算法中,如果对所有的x,h(x)<=h*(x)(3)成立,则称好h(x)为h*(x)的下界,它表示某种偏于保守的估计。采用h*(x)的下界h(x)为启发函数的A算法,称为A*算法针对八数码问题启发函数设计如下:F(n)=d(n)+p(n)(4)其中A*算法中的g(n)根据具体情况设计为d(n),意为n节点的深度,而h(n)设计为p(n),意为放错的数码与正确的位置距离之和。由于实际情况中,一个将牌的移动都是单步进行的,没有交换拍等这样的操作。所以要把所有的不在位的将牌,移动到各自的目标位置上,至少要移动从他们各自的位置到目标位置的距离和这么多次,所以最有路径的耗散值不会比该值小,因此该启发函数h(n)满足A*算法的条件。㈢主要功能在一个3*3的方棋盘上放置着1,2,3,4,5,6,7,8八个数码,每个数码占一格,且有一个空格。这些数码可以在棋盘上移动,其移动规则是:与空格相邻的数码方格可以移入空格。现在的问题是:对于指定的初始棋局和目标棋局,给出数码的移动序列。该问题称八数码难题或者重排九宫问题。五、主要代码#include<stdio.h>#include<stdlib.h>#include<math.h>//八数码状态对应的节点结构体structNode(ints[3][3];//保存八数码状态,0代表空格intf,g;//启发函数中的f和g值structNode*next;structNode*previous;//保存其父节点};intopen_N=0;〃记录Open列表中节点数目//八数码初始状态intinital_s[3][3]={2,8,3,1,6,4,7,0,5};//八数码目标状态intfinal_s[3][3]={1,2,3,8,0,4,7,6,5};///添加节点函数入口,方法:通过插入排序向指定表添加//voidAdd_Node(structNode*head,structNode*p){structNode*q;if(head->next)//考虑链表为空{q=head->next;if(p->f<head->next->f){//考虑插入的节点值比链表的第一个节点值小p->next=head->next;head->next=p;}else{while(q->next)//考虑插入节点x,形如a<=x<=b{if((q->f<p->f||q->f==p->f)&&(q->next->f>p->f||q->next->f==p->f)){p->next=q->next;q->next=p;break;}q=q->next;//}if(q->next==NULL)//考虑插入的节点值比链表最后一个元素的值更大q->next=p;}}elsehead->next=p;}////删除节点函数入口//voiddel_Node(structNode*head,structNode*p){structNode*q;q=head;while(q->next){if(q->next==p){q->next=p->next;p->next=NULL;if(q->next==NULL)return;//free(p);}q=q->next;}}////判断两个数组是否相等函数入口//intequal(ints1[3][3],ints2[3][3])(inti,j,flag=0;for(i=0;i<3i++)for(j=0;j<3j++)if(s1[i][j]!=s2[i][j])(flag=1;break;}if(!flag)return1;elsereturn0;}////判断后继节点是否存在于Open或Closed表中函数入口//intexit_Node(structNode*head,ints[3][3],structNode*Old_Node)(structNode*q=head->next;intflag=0;while(q)if(equal(q->s,s))(flag=1;Old_Node->next=q;return1;}elseq=q->next;if(!flag)return0;}////计算p(n)的函数入口〃其中p(n)为放错位的数码与其正确的位置之间距离之和//具体方法:放错位的数码与其正确的位置对应下标差的绝对值之和//intwrong_sum(ints[3][3])(inti,j,fi,fj,sum=0;//通过头插法变更节点输出次序p->previous=NULL;q=head;while(q)(q1=q->previous;q->previous=p->previous;p->previous=q;q=q1;}q=p->previous;while(q)(if(q==p->previous)printf("八数码的初始状态:\n");elseif(q->previous==NULL)printf("八数码的目标状态:\n");elseprintf("八数码的中间态%d\n”,count++);for(i=0;i<3;i++)for(j=0;j<3;j++)(printf("%4d",q->s[i][j]);if(j==2)printf("\n");}printf("f=%d,g=%d\n\n”,q->f,q->g);q=q->previous;}}////A*子算法入口:处理后继结点//voidsub_A_algorithm(structNode*Open,structNode*BESTNODE,structNode*Closed,structNode*Successor)(structNode*Old_Node=(structNode*)malloc(sizeof(structNode));Successor->previous=BESTNODE;//建立从successor返回BESTNODE的指针Successor->g=BESTNODE->g+1;//计算后继结点的g值〃检查后继结点是否已存在于Open和Closed表中,如果存在:该节点记为old_Node,比较后继结点的g值和表中old_Node节点//g值,前者小代表新的路径比老路径更好,将Old_Node的父节点改为BESTNODE,并修改其f,g值,后者小则什么也不做。//即不存在Open也不存在Closed表则将其加入OPen表,并计算其f值if(exit_Node(Open,Successor->s,Old_Node))(if(Successor->g<Old_Node->g){Old_Node->next->previous=BESTNODE;//将Old_Node的父节点改为BESTNODEOld_Node->next->g=Successor->g;//修改g值Old_Node->next->f=Old_Node->g+wrong_sum(Old_Node->s);//修改f值//排序del_Node(Open,Old_Node);Add_Node(Open,Old_Node);}}elseif(exit_Node(Closed,Successor->s,Old_Node)){if(Successor->g<Old_Node->g){Old_Node->next->previous=BESTNODE;Old_Node->next->g=Successor->g;Old_Node->next->f=Old_Node->g+wrong_sum(Old_Node->s);//排序del_Node(Closed,Old_Node);Add_Node(Closed,Old_Node);}}else{Successor->f=Successor->g+wrong_sum(Successor->s);Add_Node(Open,Successor);open_N++;}}////A*算法入口//八数码问题的启发函数为:f(n)=d(n)+p(n)〃其中A*算法中的g(n)根据具体情况设计为d(n),意为n节点的深度,而h(n)设计为p(n),〃意为放错的数码与正确的位置距离之和//voidA_algorithm(structNode*Open,structNode*Closed)//A*算法{inti,j;structNode*BESTNODE,*inital,*Successor;inital=(structNode*)malloc(sizeof(structNode));//初始化起始节点for(i=0;i<3;i++)for(j=0;j<3;j++)inital->s[i][j]=inital_s[i][j];inital->f=wrong_sum(inital_s);inital->g=0;inital->previous=NULL;inital->next=NULL;Add_Node(Open,inital);//把初始节点放入OPEN表open_N++;while(1)(if(open_N==0)(printf("failure!");return;}else(BESTNODE=get_BESTNODE(Open);//从OPEN表获取f值最小的BESTNODE,将其从OPEN表删除并加入CLOSED表中del_Node(Open,BESTNODE);open_N--;Add_Node(Closed,BESTNODE);if(equal(BESTNODE->s,final_s)){//判断BESTNODE是否为目标节点printf("success!\n");print_Path(BESTNODE);return;}〃针对八数码问题,后继结点Successor的扩展方法:空格(二维数组中的0)上下左右移动,//判断每种移动的有效性,有效则转向A*子算法处理后继节点,否则进行下一种移动else{Successor=(structNode*)malloc(sizeof(structNode));Successor->next=NULL;if(get_successor(BESTNODE,0,Successor))sub_A_algorithm(Open,BESTNODE,Closed,Successor);Successor=(structNode*)malloc(sizeof(structNode));Successor->next=NULL;if(get_successor(BESTNODE,1,Successor))sub_A_algorithm(Open,BESTNODE,Closed,Successor);Successor=(structNode*)malloc(sizeof(structNode));Successor->next=NULL;if(get_successor(BESTNODE,2,Successor))sub_A_algorithm(Open,BESTNODE,Closed,Successor);Successor=(structNode*)malloc(sizeof(structNode));Successor->next=NULL;if(get_successor(BESTNODE,3,Successor))sub_A_algorithm(Open,BESTNODE,Closed,Successor);}}}}////main()函数入口〃定义Open和Closed列表。Open列表:保存待检查节点。Closed列表:保存不需要再检查的节点//voidmain()(structNode*Open=(structNode*)malloc(sizeof(structNode));structNode*Closed=(structNode*)malloc(sizeof(structNode));Open->next=NULLOpen->previous=NULL;Closed->next=NULL;Closed->previous=NULL;A_algorithm(Open,Closed);}六、测试结果及说明2*3TOC\o"1-5"\h\z八散醐I申闾参2fl31H47fc£f>6*g"2凡散醐)尊间应11Z?。且4765F■甘■域七、实验体会。通过本次的试验,我对启发式搜索算法有了更加深入地了解。在实验中,通过对两种启发式搜索所扩在的节点数来看,p(n)看来比w(n)更加有成效,能在复杂的情况下求得更加优质的解,避免不必要的节点的扩展。但是对于估价函数h*(n)来说,他的定义趋于多元化,p(n)只是他的一个比较好的特例,对于一些复杂的搜索问题,如国际象棋问题,他就显得特别的简单。所以要更好的定义一个估价函数还有待讨论。在进行实验探究时,我还遇到一些问题,在低阶数码问题中,使用简单的宽搜或深搜便可以解决。但是在实验过程中,仍遇到很多的问题,这让我意识到自己对该算法的认识还不够充足,还要更加的努力。重庆交通大学计算机与信息学院验证性实验报告班级:软件开发专业2013级1班学号:631306050121姓名:吴文静实验项目名称:状态空间搜索实验项目性质:验证性实验实验所属课程:人工智能实验室(中心):软件中心实验室(语音楼8楼)指导教师:朱振国实验完成时间:2016年6月12日评阅意见:实验成绩:签名:年月曰一、实验目的熟悉人工智能系统中的问题求解过程;熟悉状态空间的盲目搜索和启发式搜索算法的应用;熟悉对八数码问题的建模、求解及编程语言的应用。二、实验内容及要求内容:在一个3*3的九宫中有1-8个数码及一个空格随即的摆放在其中的格子里,现在要求实验这个问题:将该九宫格调整为某种有序的形式。调整的规则是,每次只能将与空格(上、下、左、右)相邻的一个数字平移到空格中。要求:用选定的编程语言编写程序,利用不同的搜索策略进行状态空间搜索(如宽度优先搜索、深度优先搜索、有界深度优先搜索等)。三、实验设备及软件PC机一台VC6.0编程语言或其它编程语言四、设计方案㈠题目《八数码问题求解》㈡设计的主要思路1、基本数据结构分析和实现a.结点状态我采用了structNode数据类型typedefstruct_Node{intdigit[ROW][COL];intdist;//distancebetweenonestateandthedestination一个表和目的表的距离intdep;//thedepthofnode深度//Sothecommentfunction=dist+dep,估价函数值intindex;//pointtothelocationofparent父节点的位置}Node;b.发生器函数定义的发生器函数由以下的四种操作组成:将当前状态的空格上移Nodenode_up;Assign(node_up,index);//向上扩展的节点intdist_up=MAXDISTANCE;将当前状态的空格下移Nodenode_down;Assign(node_down,index);//向下扩展的节点intdist_down=MAXDISTANCE;将当前状态的空格左移Nodenode_left;Assign(node_left,index);//向左扩展的节点intdist_left=MAXDISTANCE;将当前状态的空格右移Nodenode_right;Assign(node_right,index);//向右扩展的节点intdist_right=MAXDISTANCE;通过定义结点状态和发生器函数,就解决了8数码问题的隐式图的生成问题。接下来就是搜索了。2、图的搜索策略经过分析,8数码问题中可采用的搜速策略共有:1.广度优先搜索、2.深度优先搜索、2.有界深度优先搜索、4.最好优先搜索、5.局部择优搜索,一共五种。其中,广度优先搜索法是可采纳的,有界深度优先搜索法是不完备的,最好优先和局部择优搜索法是启发式搜索法。实验时,采用了广度(宽度)优先搜索来实现。㈢主要功能对空格执行空格左移、空格右移、空格上移和空格下移这四个操作使得从初始状态到目标状态。五、主要代码#include<iostream>#include<ctime>#include<vector>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<Node>node_v;//storethenodes存储节点boolisEmptyOfOPEN()//open表是否为空{for(inti=0;i<node_v.size();i++){if(node_v[i].dist!=MAXNUM)returnfalse;}returntrue;}boolisEqual(intindex,intdigit[][COL])//判断这个最优的节点是否和目的节点一样{for(inti=0;i<ROW;i++)for(intj=0;j<COL;j++){if(node_v[index].digit[i][j]!=digit[i][j])returnfalse;}returntrue;}ostream&operator<<(ostream&os,Node&node){for(inti=0;i<ROW;i++){for(intj=0;j<COL;j++)os<<node.digit[i][j]<<'';os<<endl;}returnos;}voidPrintSteps(intindex,vector<Node>&rstep_v)//输出每一个遍历的节点深度遍历{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<<"Step"<<rstep_v.size()-i<<endl<<rstep_v[i]<<endl;}voidSwap(int&a,int&b){intt;t=a;a=b;b=t;}voidAssign(Node&node,intindex){for(inti=0;i<ROW;i++)for(intj=0;j<COL;j++)node.digit[i][j]=node_v[index].digit[i][j];}intGetMinNode()//找到最小的节点的位置即最优节点{intdist=MAXNUM;intloc;//thelocationofminimizenodefor(inti=0;i<node_v.size();i++){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&node){for(inti=0;i<node_v.size();i++){if(isEqual(i,node.digit))returnfalse;}returntrue;}intDistance(Node&node,intdigit[][COL]){intdistance=0;boolflag=false;for(inti=0;i<ROW;i++)for(intj=0;j<COL;j++)for(intk=0;k<ROW;k++){for(intl=0;l<COL;l++){if(node.digit[i][j]==digit[k][l]){distance+=abs(i-k)+abs(j-l);flag=true;break;}elseflag=false;}if(flag)break;}returndistance;}intMinDistance(inta,intb){return(a<b?a:b);}voidProcessNode(intindex){intx,y;boolflag;for(inti=0;i<ROW;i++){}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<<"Inputsource:"<<endl;for(inti=0;i<ROW;i++)//输入初始的表for(intj=0;j<COL;j++){cin>>number;src.digit[i][j]=

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论