九宫格的启发式搜索

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

九宫格的启发式搜索

班级:计算机一班

姓名:覃荣锦

学号:*******

目录

一、实验目的 (3)

二、实验语言环境 (3)

三、实现设计 (3)

1.状态表示: (3)

2.算法介绍: (3)

1)广度优先搜索: (3)

2)深度优先搜索: (4)

3.初始化节点以及判断目标节点 (5)

4.拓展节点 (6)

5.搜索算法 (7)

四、程序全部代码 (8)

五、分析总结 (15)

1.数据结构分析 (15)

2.拓展方法分析 (15)

3.搜索算法分析 (15)

六、运行结果 (16)

七、遇见的问题以及解决方法 (16)

一、实验目的

加深对局部择优搜索以及全局择优搜索的熟悉程度。

了解局部择优搜索以及全局择优搜索的区别。

二、实验语言环境

系统:微软Window7系统

开发工具:visual c/c++ 6.0

语言:c语言

三、实现设计

1.状态表示:

九宫格状态以一组一维数组表示。1~8分别表示8个对应的数字,0表示空格,数据结构如下:

Typedef struct

{

Int data[9];

}Data;

九宫格节点为以线性表表示的树的节点,因此需要加入指向该节点父母的指针,在这里用下标表示,同时由于不同节点有不同的估值,因此需要加入表示其值变量。完整的数据结构如下:

typedef struct

{

int data[9];

int parent;

int value;

} Data;

2.算法介绍:

1)局部择优搜索:

第一步:把初始节点S0放入open表。

第二步:如果open表为空,则问题无解,退出。

第三步:把OPEN表的第一个节点取出放入CLOSE表,记该节点为节点n。

第四步:观察节点n是否为目标节点,若是,则求得问题的解,退出。

第五步:拓展节点n,将扩展的的节点排序后放入open表,将合法节点放入open表中。然后转到第二步。

2)全局择优搜索:

第一步:把初始节点S0放入open表。

第二步:如果open表为空,则问题无解,退出。

第三步:把OPEN表的最后一个节点取出放入CLOSE表,记该节点为节点n。

第四步:观察节点n是否为目标节点,若是,则求得问题的解,退出。

第五步:拓展节点n,将合法节点放入open表中。排序OPEN表。然后转到第二步。

3.辅助矩阵介绍

在本程序中,为了执行提高效率,在拓展和局面评估这两部分采用了矩阵作为辅助。

拓展辅助矩阵如下:

const static int check[9][4]=

{

{1,3,9,9},{0,2,4,9},{1,5,9,9},

{0,4,6,9},{1,3,5,7},{2,4,8,9},

{3,7,9,9},{4,6,8,9},{5,7,9,9}

};

在九宫格中,第0块可以和1、3块交换,第1块可以和0、2、4块交换……根据这个特点,本程序中生成如上的矩阵,对于第i块,它的可交换块为check[i][0]、check[i][1]、check[i][2]等等。

评估辅助矩阵如下:

const static int a[9][9]=

{

0,1,2,1,2,3,2,3,4,//1

1,0,1,2,1,2,3,2,3,//2

2,1,0,3,2,1,4,3,2,//3

1,2,3,0,1,2,1,2,3,//4

2,1,2,1,0,1,2,1,2,//5

3,2,1,2,1,0,3,2,1,//6

2,3,4,1,2,3,0,1,2,//7

3,2,3,2,1,2,1,0,1,//8

4,3,2,3,2,1,2,1,0,//9

};

该矩阵是一个二维矩阵,矩阵的值a[i][j]表示九宫格第i块和第j块的距离。

这可以很方便地求出第i块移动到目标点的代价。

比如,数字为n的块当前位置为p,则我们可以通过取a[n][p]的值直接求得它移动到目标花费的代价。当然,值为0的块目标位置是9,因此我们为它取值应该为a[9][p]。

4.初始化节点以及判断目标节点

由于硬件的局限性,我们不能保证任何局面都能在一遍内找到走法,因此我们在本程序中添加自动生成在当前硬件条件下可破解的局面。思路为从目标局面开始随机移动30~40步生成一个初始局面。并将该初始局面作为初始节点。

算法如下:

void InitData(int data[9])//随机生成可破解局面

{

srand((unsigned)time(NULL));//

int a[9]={1,2,3,4,5,6,7,8,0};

int k=rand()%10+30;

int j,l,temp;

while(k>=0)

{

for(l=0;l<9;l++)

if(a[l]==0) break;

j=rand()%4;

k--;

if(check[l][j]!=9)

{

temp=a[check[l][j]];

a[check[l][j]]=a[l];

a[l]=temp;

}

}

for(j=0;j<9;j++)

data[j]=a[j];

}

void Init(int data[9])

{

for(int i=0;i<9;i++)

open[opentop].data[i]=data[i];

open[opentop].parent=-1;

open[opentop].value=GetValue(open[opentop].data);

opentop++;

}

判断目标节点算法如下:

bool Checkwin(int data[9])

{

for(int i=0;i<8;i++)

if(data[i]!=i+1) return 0;

return 1;

}

相关文档
最新文档