启发式搜索八数码问题Word下载.docx

上传人:b****6 文档编号:17391906 上传时间:2022-12-01 格式:DOCX 页数:14 大小:78.73KB
下载 相关 举报
启发式搜索八数码问题Word下载.docx_第1页
第1页 / 共14页
启发式搜索八数码问题Word下载.docx_第2页
第2页 / 共14页
启发式搜索八数码问题Word下载.docx_第3页
第3页 / 共14页
启发式搜索八数码问题Word下载.docx_第4页
第4页 / 共14页
启发式搜索八数码问题Word下载.docx_第5页
第5页 / 共14页
点击查看更多>>
下载资源
资源描述

启发式搜索八数码问题Word下载.docx

《启发式搜索八数码问题Word下载.docx》由会员分享,可在线阅读,更多相关《启发式搜索八数码问题Word下载.docx(14页珍藏版)》请在冰豆网上搜索。

启发式搜索八数码问题Word下载.docx

计算

如果

既不在OPEN表中,又不在CLOCED表中,则用估价函数

它添入OPEN表中。

加一指向其父节点

的指针,以便一旦找到目标节点时记住一个解答路径;

已在OPEN表或CLOSED表中,则比较刚刚对

计算过的

和前面计算过的该节点在表中的

值。

如果新的

较小,则

(I)以此新值取代旧值。

(II)从

指向

,而不是指向他的父节点。

(III)如果节点

在CLOSED表中,则把它移回OPEN表中。

7转向②,即GOTO②。

4.估价函数

计算一个节点的估价函数,可以分成两个部分:

1、已经付出的代价〔起始节点到当前节点〕;

2、将要付出的代价〔当前节点到目标节点〕。

节点n的估价函数

定义为从初始节点、经过n、到达目标节点的路径的最小代价的估计值,即

=

+

是从初始节点到达当前节点n的实际代价;

是从节点n到目标节点的最正确路径的估计代价,表达出搜索过程中采用的启发式信息〔背景知识〕,称之为启发函数。

所占的比重越大,越趋向于宽度优先或等代价搜索;

反之,

的比重越大,表示启发性能就越强。

5.实验代码

为方便起见,目标棋局为不变

(1)以下代码估价函数为深度+错放棋子个数

(2)假设估价函数为深度+每个棋子与其目标位置之间的距离总和,则加入估价函数

intcalvalue1(inta[])//不在位棋子数

{

intc=0;

intb=0;

for(inti=0;

i<

=8;

i++)

for(intj=0;

j<

j++)

if(a[i]=goal[j])

if(goal[j]!

=0)

c=c+abs(i%3-j%3)+abs((i-i%3)/3+(j-j%3)/3);

returnc;

}

(3)宽度搜索采用OPEN->

jiedian.f=depth;

(4)深度搜索采用OPEN->

jiedian.f=-depth;

源代码:

1.#include"

stdio.h"

2.

3.intgoal[9]={1,2,3,8,0,4,7,6,5},sgoal[9];

//goal为棋盘的目标布局,并用中间状态sgoal与之比较

4.

5.structBoard

6.{

7.intshuzu[9];

8.intd,f,e;

//d:

深度;

f:

启发函数;

e:

记录前一次的扩展节点

9.};

10.

11.structNodeLink

12.{

13.Boardjiedian;

14.NodeLink*parent;

15.NodeLink*previous;

16.NodeLink*next;

17.NodeLink*path;

18.};

19.//更新纪录八数码的状态

20.voidsetboard(inta[],intb[],intflag)//flag=0,写棋子;

flag=1,写棋盘

21.{

22.for(inti=0;

23.if(flag)

24.a[b[i]]=i;

25.else

26.b[a[i]]=i;

27.}

28.//计算启发值的函数

29.intcalvalue(inta[])//不在位棋子数

30.{

31.intc=0;

32.for(inti=0;

33.if(a[i]!

=goal[i])

34.if(goal[i]!

35.c++;

36.returnc;

37.}

38.//生成一个新节点的函数

39.NodeLink*newnode(NodeLink*TEM,intdepth,intflag)

40.{

41.NodeLink*temp=newNodeLink;

42.for(inti=0;

43.temp->

jiedian.shuzu[i]=TEM->

jiedian.shuzu[i];

44.switch(flag)

45.{

46.case1:

47.{

48.temp->

jiedian.shuzu[0]--;

49.temp->

jiedian.shuzu[sgoal[temp->

jiedian.shuzu[0]]]++;

//向左移

50.break;

51.}

52.case2:

53.{

54.temp->

jiedian.shuzu[0]++;

55.temp->

jiedian.shuzu[0]]]--;

//向右移

56.break;

57.}

58.case3:

59.{

60.temp->

jiedian.shuzu[0]-=3;

61.temp->

jiedian.shuzu[0]]]+=3;

//向上移

62.break;

63.}

64.case4:

65.{

66.temp->

jiedian.shuzu[0]+=3;

67.temp->

jiedian.shuzu[0]]]-=3;

//向下移

68.break;

69.}

70.}

71.temp->

jiedian.d=depth+1;

72.setboard(sgoal,temp->

jiedian.shuzu,1);

73.temp->

jiedian.f=temp->

jiedian.d+calvalue(sgoal);

74.temp->

jiedian.e=flag;

75.temp->

parent=TEM;

76.returntemp;

77.}

78.//把新节点加入OPEN队列

79.NodeLink*addnode(NodeLink*head,NodeLink*node)//把node插入到head链中

80.{

81.NodeLink*TEM;

82.TEM=head;

83.head=node;

84.head->

next=TEM;

85.head->

previous=NULL;

86.if(TEM)

87.TEM->

previous=head;

//TEM已为空,无需操作

88.returnhead;

89.}

90.

91.//求启发值最小的结点

92.NodeLink*minf(NodeLink*head)

93.{

94.NodeLink*min,*forward;

95.min=head;

96.forward=head;

97.while(forward)

98.{

99.if(min->

jiedian.f>

forward->

jiedian.f)

100.min=forward;

101.forward=forward->

next;

102.}

103.returnmin;

104.}

105.

106.intmain()

107.{

108.intdepth=0;

109.intsource[9];

110.inti,j;

111.

112.NodeLink*OPEN=newNodeLink;

113.NodeLink*TEMP,*TEM;

114.

115.printf("

请输入初始状态:

\n"

);

116.for(i=0;

i<

9;

117.scanf_s("

%d"

&

source[i]);

118.

119.setboard(source,OPEN->

jiedian.shuzu,0);

120.OPEN->

jiedian.d=depth;

121.OPEN->

jiedian.e=0;

122.OPEN->

jiedian.f=depth+calvalue(source);

123.OPEN->

next=NULL;

124.OPEN->

125.OPEN->

parent=NULL;

126.

127.while(OPEN)

128.{

129.TEMP=minf(OPEN);

//求具有最小启发值的节点

130.setboard(sgoal,TEMP->

//写棋盘

131.if(!

calvalue(sgoal))

132.break;

133.if(TEMP!

=OPEN)//如果不是第一个节点

134.{

135.TEMP->

previous->

next=TEMP->

136.TEMP->

next->

previous=TEMP->

previous;

137.}

138.else//是第一个节点

139.{

140.if(OPEN->

next)//如果还有节点

141.{

142.OPEN=OPEN->

143.OPEN->

144.}

145.elseOPEN=NULL;

//否则置为空

146.}

147.

148.if(TEMP->

jiedian.shuzu[0]-1>

=0&

&

TEMP->

jiedian.e!

=2)//防止棋子回到原状态

149.OPEN=addnode(OPEN,newnode(TEMP,depth,1));

150.if(TEMP->

jiedian.shuzu[0]+1<

=8&

=1)

151.OPEN=addnode(OPEN,newnode(TEMP,depth,2));

152.if(TEMP->

jiedian.shuzu[0]-3>

=4)

153.OPEN=addnode(OPEN,newnode(TEMP,depth,3));

154.if(TEMP->

jiedian.shuzu[0]+3<

=3)

155.OPEN=addnode(OPEN,newnode(TEMP,depth,4));

156.depth++;

157.}

158.

159.if(OPEN)//如有解,则打印出解的步骤

160.{

161.TEMP->

path=NULL;

162.while(TEMP->

parent)//每次回溯父节点,生成路径

163.{

164.TEMP->

parent->

path=TEMP;

165.TEMP=TEMP->

parent;

166.}

167.j=0;

168.while(TEMP->

path)

169.{

170.setboard(sgoal,TEMP->

171.printf("

第%d步:

j);

172.for(i=0;

=2;

173.printf("

%d"

sgoal[i]);

174.printf("

\n"

175.for(i=3;

=5;

176.printf("

177.printf("

178.for(i=6;

179.printf("

180.printf("

181.TEMP=TEMP->

path;

182.j++;

183.}

184.setboard(sgoal,TEMP->

185.printf("

186.for(i=0;

187.printf("

188.printf("

189.for(i=3;

190.printf("

191.printf("

192.for(i=6;

193.printf("

194.printf("

195.}

196.else

197.printf("

无法求解!

"

198.}

(1)以上代码估价函数为深度+错放棋子个数

(2)假设估价函数为深度+每个棋子与其目标位置之间的距离总和,则函数改为

intcalvalue(inta[])//不在位棋子数

6.输出结果:

〔输入为:

目标状态为:

(1)估价函数为深度+错放棋子个数

(2)估价函数为深度+每个3棋子与其目标位置之间的距离总和

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 外语学习 > 英语考试

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1