八数码难题的搜索求解演示.doc_第1页
八数码难题的搜索求解演示.doc_第2页
八数码难题的搜索求解演示.doc_第3页
八数码难题的搜索求解演示.doc_第4页
八数码难题的搜索求解演示.doc_第5页
已阅读5页,还剩13页未读 继续免费阅读

下载本文档

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

文档简介

人工智能实验报告 学 院:信息科学与工程学院班 级: 自动化0901班 学 号: 0909090316 姓 名: 孙锦岗指导老师: 刘丽珏 日 期:2011年12月20日一、 实验名称、目的及内容实验名称: 八数码难题的搜索求解演示实验目的:加深对图搜索策略概念的理解,掌握搜索算法。实验内容要求:以八数码难题为例演示广度优先或深度优先搜索、A算法(本实验使用的是广度优先搜索)的搜索过程,争取做到直观、清晰地演示算法。八数码难题:在33方格棋盘上,分别放置了标有数字1,2,3,4,5,6,7,8的八张牌,初始状态S0,目标状态如图所示,可以使用的操作有:空格上移,空格左移,空格右移,空格下移。试编一程序实现这一搜索过程。二、实验原理及基本技术路线图实验原理:八数码问题中,程序产生的随机排列转换成目标共有两种可能,而且这两种不可能同时成立,也就是奇数排列和偶数排列。我们可以把一个随机排列的数组从左到右从上到下用一个数组表示,例如,其中代表空格。它在奇序列位置上。在这个数组中我们首先计算它能够重排列出来的结果,公式就是:(),其中(),就是一个数他前面比这个数小的数的个数,为奇数和偶数个有一种解法。那么上面的数组我们就可以解出它的结果。数据结构:本实验使用的数据结构是队列,应用队列先进先出的特点来实现对节点的保存和扩展。首先建立一个队列,将初始结点入队,并设置队列头和尾指,然后取出队列(头指针所指)的结点进行扩展,从它扩展出子结点,并将这些结点按扩展的顺序加入队列,然后判断扩展出的新结点与队列中的结点是否重复,如果重复则,否则记录其父结点,并将它加入队列,更新队列尾指针,然后判断扩展出的结点是否是目标结点,如果是则显示路径,程序结束。否则如果队列头的结点可以扩展,直接返回第二步。否则将队列头指针指向下一结点,再返回第二步,知道扩展出的结点是目标结点结束,并显示路径。算法分析:九宫问题的求解方法就是交换空格()位置,直至到达目标位置为止。如图所示:2 8316475 8715263487152346 8715263487152346 因此可知:九宫的所以排列有!种,也就是种排法,数据量是非常大的,我使用广度搜索,需要记住每一个结点的排列形式,要是用数组记录的话会占用很多的内存,我们把数据进行适当的压缩。使用形式保存,压缩形式是每个数字用位表示,这样就是个字节,由于的二进制表示形式,不能用位表示,我使用了一个小技巧就是将表示位,然后用多出来的个字表示所在的位置,就可以用表示了。用移位和或操作将数据逐个移入,比乘法速度要快点。定义了几个结果来存储遍历到了结果和搜索完成后保存最优路径。算法描述:过程 BREADTH-SEARCH(1) G:=G0(G0=s),OPEN:=(s),CLOSE:=( );(2) LOOP:IF OPEN=( ) THEN EXIT(FAIL);(3) N:=FIRST(OPEN);(4) IF GOAL(n) THEN EXIT(SUCCESS);(5) RENMOVE(n,OPEN),ADD(n,CLOSED);(6) EXPAND(n)mi,G:=ADD(mi,G);(7) 结点放在OPEN表的后面,使深度浅的结点可优先扩展。广度优先搜索的源代码如下:void Bfs() queue Queue; Queue.push(org); HashTable org.myindex = -1; while( NOT Queue.empty() ) Map node = Queue.front(); Queue.pop(); for(int k =0 ; k 4; k + ) Map tmp = node; tmp.position = node.position + derectionk; if(tmp.position 8 | ( k 1 & tmp.position / 3 != node.position /3 ) ) continue; tmp.myindex = HashValue( node , k ); if(0 != HashTabletmp.myindex ) continue; tmp.detail node.position = tmp.detail tmp.position ; / 移动空格 tmp.detail tmp.position = 0 ; HashTabletmp.myindex = node.myindex; / 状态记录到hashtable中 if( node.myindex = EndIndex ) return ; Queue.push( tmp ); return ; 实验流程图:开始输入要排序的08数码序列建立一个队列,将初始结点入队,并设置队列头和尾指针取出队列头(头指针所指)的结点进行扩展,从它扩展出子结点,并将这些结点按扩展的顺序加入队列判断扩展出的新结点与队列中的结点是否重复结点,并将这些结点按扩展的顺序加入队列否记录其父结点,并将它加入队列,更新队列尾指针扩展出子结点,并将这些结点按扩展的顺序加入队列队列头的结点可以扩展,直接返回第二步。否则将队列头指针指向下一结点,再返回第二步。判断扩展出的结点是否是目标结点,是是否显示路径程序结束三、所用仪器、材料(设备名称、型号、规格等或使用软件)硬件:个人计算机 软件: Microsoft Visual C+ 6.0 四、实验方法、步骤(或:程序代码或操作过程)1.实验步骤(1)运行Microsoft Visual C+ 6.0软件,新建工作空间,得文档。(2)输入源程序代码,进行编译,调试运行。(3)运行结果,按提示要求输入18这八个数,进行程序测验。2.实验源程序#include #include #include #include #include using namespace std; #define HashTableSize 362881 #define NOT ! #define UP 0 #define DOWN 1 #define LEFT 2 #define RIGHT 3 #define Bit char typedef struct maps Bit detail9; int myindex; / 记录自己节点在hash表中的位置 Bit position; / 记录 空格(0)在序列中的位置 Map,*PMap; Map org; / 初始状态 int EndIndex; /目标,上移 ,下移 , 左移 ,右移 int const derection4 = -3 , 3 , -1 , 1 ;/ 可移动的四个方向 int const Factorial9 = 40320 , 5040 , 720 , 120 , 24 , 6 , 2 , 1 , 1 ; int HashTableHashTableSize=0;/hash表,其中记录的是上一个父节点对应的位置 /*八数码的输入(在这里不做任何输入检查,均认为输入数据是正确的)*/void input() int i,j; int sum , count ,index ; for(i = 0 ; i 9 ; i + ) scanf(%1d, &org.detail i ); org.detail i | (org.position = i) ; for(i = 0 ; i 9 ; i + ) /计算逆序 if( 0 = org.detail i ) continue; for(j = 0 ; j i; j + ) sum += ( 0 != org.detail j & org.detail j org.detail i ); for( i = 0 , index = 0 ; i 9 ; i + ) / 计算初始状态的hash值 for(j = 0 , count = 0 ; j org.detail i ; index += Factorial org.detail i * count; org.myindex = index + 1 ; EndIndex = sum%2 ? 161328:322561; / 目标状态的hash值 return; /*hash值的计算*Parent:父状态的hash值*direct:移动的方向*/ inline int HashValue(Map& Parent , int& direct ) int i = Parent.position ; int newindex = Parent.myindex ; Bit *p = Parent.detail; switch(direct) case UP : newindex -= 3*40320 ; newindex += ( p i - 2 p i - 3 ) ? ( Factorial p i - 3 ) : ( - Factorial p i - 2 ); newindex += ( p i - 1 p i - 3 ) ? ( Factorial p i - 3 ) : ( - Factorial p i - 1 ); break; case DOWN : newindex += 3*40320 ; newindex -= ( p i + 2 p i + 3 ) ? ( Factorial p i + 3 ) : ( - Factorial p i + 2 ); newindex -= ( p i + 1 p i + 3 ) ? ( Factorial p i + 3 ) : ( - Factorial p i + 1 ); break; case LEFT : return newindex - 40320; break; case RIGHT : return newindex + 40320; break; return newindex; /* * * 广度优先搜索*/ void Bfs() queue Queue; Queue.push(org); HashTable org.myindex = -1; while( NOT Queue.empty() ) Map node = Queue.front(); Queue.pop(); for(int k =0 ; k 4; k + ) Map tmp = node; tmp.position = node.position + derectionk; if(tmp.position 8 | ( k 1 & tmp.position / 3 != node.position /3 ) ) continue; tmp.myindex = HashValue( node , k ); if(0 != HashTabletmp.myindex ) continue; tmp.detail node.position = tmp.detail tmp.position ; / 移动空格 tmp.detail tmp.position = 0 ; HashTabletmp.myindex = node.myindex; / 状态记录到hashtable中 if( node.myindex = EndIndex ) return ; Queue.push( tmp ); return ; /* 通过hash表中记录的进行查找路径*/ void FindPath() int nowindex; int count =0 ; int nixu9, result9; int i, j , k ; stack Stack; Stack.push(EndIndex); nowindex = EndIndex; while( -1 != HashTable nowindex ) Stack.push(HashTable nowindex ); nowindex = HashTable nowindex ; printf(共需: %d 步n,Stack.size()-1); getchar(); while( NOT Stack.empty() nowindex = Stack.top() - 1 ; Stack.pop(); for( i = 0 ; i 9; i + ) / 计算出逆序 nixui = nowindex / Factorial i ; nowindex %= Factorial i ; memset( result , -1 , 9 *sizeof(int); for( i =0 ; i 9 ; i + ) / 根据逆序计算排列 for( j = 0 , k = nixui ; j 9 ; j + ) if(resultj = -1 ) k -; if( k 0 ) break; resultj = i ; for( i =0 ; i 9 ; i + ) printf(%3d,resulti); if( 2 = i % 3 ) printf(n); if(0 != Stack.size() ) printf(n 第%d步n,+count); getchar(); printf(nThe End!n); ret

温馨提示

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

评论

0/150

提交评论