西电人工智能大作业

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

人工智能大作业

学生:021151**

021151**

时间:2013年12月4号

一.启发式搜索解决八数码问题

1. 实验目的

问题描述:现有一个3*3的棋盘,其中有0-8一共9个数字,0表示空格,其他的数字可以和0交换位置(只能上下左右移动)。给定一个初始状态和一个目标状态,找出从初始状态到目标状态的最短路径的问题就称为八数码问题。

例如:实验问题为

从初始状态:

要求编程解决这个问题,给出解决这个问题的搜索树以及从初始节点到目标

到目标状态:

节点的最短路径。

2.实验设备及软件环境

利用计算机编程软件Visual C++ 6.0,用C语言编程解决该问题。

3.实验方法

(1).算法描述:

①.把初始节点S放到OPEN表中,计算()

f S,并把其值与节点S联系起

来。

②.如果OPEN表是个空表,则失败退出,无解。

③.从OPEN表中选择一个f值最小的节点。结果有几个节点合格,当其

中有一个为目标节点时,则选择此目标节点,否则就选择其中任一节点作为节点i。

④.把节点i从OPEN表中移出,并把它放入CLOSED的扩展节点表中。

⑤.如果i是目标节点,则成功退出,求得一个解。

⑥.扩展节点i,生成其全部后继节点。对于i的每一个后继节点j:

a.计算()

f j。

b.如果j既不在OPEN表中,也不在CLOSED表中,则用估价函数f把

它添加入OPEN表。从j加一指向其父辈节点i的指针,以便一旦找

到目标节点时记住一个解答路径。

c.如果j已在OPEN表或CLOSED表上,则比较刚刚对j计算过的f值

和前面计算过的该节点在表中的f值。如果新的f值较小,则

I.以此新值取代旧值。

II.从j指向i,而不是指向它的父辈节点。

III.如果节点j在CLOSED表中,则把它移回OPEN表。

⑦转向②,即GO TO ②。

(2).流程图描述:

(3).程序源代码:

#include

#include

struct node{

int number[3][3];//用二维数组存放8数码

int W;//W表示与目标状态相比错放的数码数

int Depth;//记录当前节点的深度

struct node *parent;//指向父节点的指针

struct node *next;//指向链表中下一个节点的指针};

int CounterW(int Number[3][3])

{//函数说明:计算当前状态与目标状态的W值int i,j;

int W=0;

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

for(i=0; i<3; i++)

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

if(Number[i][j] != Desnode[i][j])

W++;

return W;

}

void PrintNode(node *A)

{

int i,j;

for(i=0; i<3; i++)

{

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

printf("%d ",A->number[i][j]);

printf("\n");

}

printf("\n");

}

int CheckNode(node *open, node *close, int a[3][3]) {//检验该节点状态是否出现过的子程序

int CheckFlag=0;

int flag1,flag2;

node *p=open;

node *q=close;

while(p != NULL)

{

flag1=0;

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

{

for(int j=0; j<3; j++)

if(a[i][j]==p->number[i][j])

flag1++;

}

if(flag1 == 9)

break;

else

p=p->next;

}

while(q != NULL)

{

flag2=0;

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

{

for(int j=0; j<3; j++)

if(a[i][j] == q->number[i][j])

flag2++;

}

if(flag2 == 9)

break;

else

q=q->next;

}

if((flag1==9) || (flag2==9))

CheckFlag=1;//如果出现过,置标志位为1

return CheckFlag;

}

struct node *FindNextNode(node *Prenode, node *open, node *close)

{ //扩展Prenode指向的节点,并将扩展所得结点组成一条单链表int i,j,m,n; //循环变量

int temp; //临时替换变量

int flag=0;

int a[3][3];//临时存放二维数组

struct node *p, *q, *head;

head=(node *)malloc(sizeof(node));//head指向该链表首结点,并且作为返回值

p=head;

q=head;

head->next=NULL;//初始化

for(i=0;i<3;i++)//找到二维数组中0的位置

相关文档
最新文档