八数码难题的搜索求解演示

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 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;

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

相关文档
最新文档