八数码难题的搜索求解演示
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
人工智能实验报告
学院:信息科学与工程学院
班级:自动化0901班
学号:
姓名:孙锦岗
指导老师:刘丽珏
日期:2011年12月20日
一、实验名称、目的及内容
实验名称:
八数码难题的搜索求解演示
实验目的:
加深对图搜索策略概念的理解,掌握搜索算法。
实验内容要求:
以八数码难题为例演示广度优先或深度优先搜索、A算法(本实验使用的是广度优先搜索)的搜索过程,争取做到直观、清晰地演示算法。
八数码难题:在3×3方格棋盘上,分别放置了标有数字1,2,3,4,5,6,7,8的八张牌,初始状态S0,目标状态如图所示,可以使用的操作有:空格上移,空格左移,空格右移,空格下移。试编一程序实现这一搜索过程。
二、实验原理及基本技术路线图
实验原理:
八数码问题中,程序产生的随机排列转换成目标共有两种可能,而且这两种不可能同时成立,也就是奇数排列和偶数排列。我们可以把一个随机排列的数组从左到右从上到下用一个数组表示,例如{8,
7,1,5,2,6,3,4,0}其中0代表空格。它在奇序列位置上。
在这个数组中我们首先计算它能够重排列出来的结果,公式就是:∑(F(X))=Y,其中F(X),就是一个数他前面比这个数小的数的个数,Y为奇数和偶数个有一种解法。那么上面的数组我们就可以解出它的结果。
数据结构:
本实验使用的数据结构是队列,应用队列先进先出的特点来实现对节点的保存和扩展。首先建立一个队列,将初始结点入队,并设置队列头和尾指,然后取出队列(头指针所指)的结点进行扩展,从它扩展出子结点,并将这些结点按扩展的顺序加入队列,然后判断扩展出的新结点与队列中的结点是否重复,如果重复则,否则记录其父结点,并将它加入队列,更新队列尾指针,然后判断扩展出的结点是否是目标结点,如果是则显示路径,程序结束。否则如果队列头的结点可以扩展,直接返回第二步。否则将队列头指针指向下一结点,再返回第二步,知道扩展出的结点是目标结点结束,并显示路径。
算法分析:
九宫问题的求解方法就是交换空格(0)位置,直至到达目标位置为止。如图所示:
因此可知:九宫的所以排列有9!种,也就是种排法,数据量是非常大的,我使用广度搜索,需要记住每一个结点的排列形式,要是用数组记录的话会占用很多的内存,我们把数据进行适当的压缩。使用DWORD形式保存,压缩形式是每个数字用3位表示,这样就是3×9=27个字节,由于8的二进制表示形式1000,不能用3位表示,我使用了一个小技巧就是将8表示位000,然后用多出来的5个字表示8所在的位置,就可以用DWORD表示了。用移位和或操作将数据逐个移入,比乘法速度要快点。定义了几个结果来存储遍历到了结果和搜索完成后保存最优路径。
算法描述:
过程 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.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 + derection[k];
if(tmp.position < 0 || tmp.position > 8 || ( k > 1 && tmp.position / 3 != node.position /3 ) )
continue;
tmp.myindex = HashValue( node , k );
if(0 != HashTable[tmp.myindex] ) continue;
tmp.detail[ node.position ] = tmp.detail[ tmp.position ] ;
// 移动空格
tmp.detail[ tmp.position ] = 0 ;
HashTable[tmp.myindex] = node.myindex; // 状态记录到hashtable中
if( node.myindex == EndIndex ) return ;
Queue.push( tmp );
}
}
return ; }
实验流程图:
三、所用仪器、材料(设备名称、型号、规格等或使用软件)
硬件:个人计算机
软件:Microsoft Visual C++ 6.0
四、实验方法、步骤(或:程序代码或操作过程)
1.实验步骤
(1)运行Microsoft Visual C++ 6.0软件,新建工作空间,
得文档。
(2)输入源程序代码,进行编译,调试运行。
(3)运行结果,按提示要求输入1—8这八个数,进行程序测验。
2.实验源程序
#include
#include
#include
#include
#include
using namespace std;
#define HashTableSize
#define NOT !
#define UP 0
#define DOWN 1