野人过河问题

问题描述:设有3个传教士(Missionaries)和3个野人(Cannibals)来到河边,打算乘一只船从右岸渡到左岸去。该船的最大负荷能力为两个人(k=2)。在任何情况下:如果野人人数超过传教士人数,那么野人就会把传教士吃掉。他们怎样才能用这条船安全地把所有人都渡过河去呢?(提示:用状态空间来描述,其综合数据库:用三元数组表示, m表示传教士,c表示野人,b表示船状态)

[cpp]view plaincopyprint?

1.#include <iostream> 

2.#include <vector> 

3.#include <list> 

4.using namespace std; 

5.

6.typedef struct 

7.

8.int m;//表示传教士

9.int c;// 表示野人

10.int b;//船状态

11.}MCNode; 

12.

13.list<MCNode> fringe;//相当于队列

14.vector<MCNode> closed;//closed

15.

16.//判断是否是目标结点

17.bool IsGoal(MCNode tNode) 

18.

19.if(tNode.m==0&&tNode.c==0&&tNode.b==0) 

20.return true; 

21.else 

22.return false; 

23.

24.//判断是否是合法状态

25.bool IsLegal(MCNode tNode) 

26.

27.if(tNode.m>=0&&tNode.m<=3&&tNode.c>=0&&tNode.c<=3) 

28.

29.if((tNode.m==tNode.c)||(tNode.m==3)||(tNode.m==0)) 

30.return true; 

31.else 

32.return false; 

33.

34.else 

35.return false; 

36.

37.//重载运算符,判断两结构体是否相等

38.bool operator==(MCNode m1,MCNode m2) 

39.

40.if(m1.m==m2.m&&m1.c==m2.c&&m1.b==m2.b) 

41.return true; 

42.else 

43.return false; 

44.

45.//判断是否已在closed表中

46.bool IsClosed(MCNode tNode) 

47.

48.int i; 

49.for(i=0;i!=closed.size();i++) 

50.

51.if(tNode==closed[i]) 

52.return true; 

53.

54.if(i==closed.size()) 

55.return false; 

56.

57.void ExpandNode(MCNode tNode,int b,list<MCNode> &fringe) 

58.

59.MCNode node[5];//应用5条规则集生成新结点

60.if(b==1) 

61.

62.for(int i=0;i<5;i++) 

63.node[i].b=0; 

64.node[0].m=tNode.m-1; 

65.node[0].c=tNode.c; 

66.node[1].m=tNode.m; 

67.node[1].c=tNode.c-1; 

68.node[2].m=tNode.m-1; 

69.node[2].c=tNode.c-1; 

70.node[3].m=tNode.m-2; 

71.node[3].c=tNode.c; 

72.node[4].m=tNode.m; 

73.node[4].c=tNode.c-2; 

74.

75.else 

76.

77.for(int i=0;i<5;i++) 

78.node[i].b=1; 

79.node[0].m=tNode.m+1; 

80.node[0].c=tNode.c; 

81.node[1].m=tNode.m; 

82.node[1].c=tNode.c+1; 

83.node[2].m=tNode.m+1; 

84.node[2].c=tNode.c+1; 

85.node[3].m=tNode.m+2; 

86.node[3].c=tNode.c; 

87.node[4].m=tNode.m; 

88.node[4].c=tNode.c+2; 

89.

90.for(int i=0;i<5;i++) 

91.if(IsLegal(node[i])&&!IsClosed(node[i])) 

92.fringe.push_front(node[i]);//队列后进先出,深度优先搜索,最后得到一条最小解序列

93.// fringe.push_back(node[i]);//队列后进后出,广度优先搜索,最后得到最小解序列状态空间图

94.

95.void main() 

96.

97.MCNode InitNode,unode; 

98.InitNode.m=3; 

99.InitNode.c=3; 

100.InitNode.b=1; 

101.fringe.push_back(InitNode);//将初始状态空间加入到队列

102.while(!fringe.empty()) 

103.

104.unode=fringe.front(); 

105.fringe.pop_front(); 

106.if(IsGoal(unode)) 

107.

108.closed.push_back(unode); 

109.for(int i=0;i!=closed.size();i++) 

110.cout<<closed[i].m<<","<<closed[i].c<<","<<closed[i].b<<endl; 

111.break; 

112.

113.if(!IsClosed(unode)) 

114.

115.closed.push_back(unode); 

116.ExpandNode(unode,unode.b,fringe); 

117.

118.

119.

120./*渡法说明:

121.

122.2个野人去,1个野人回

123.

124.2个野人去,1个野人回

125.

126.2个传教士去,1个野人与1个传教士回

127.

128.2个传教士去,1个野人回

129.

130.2个野人去,1个野人回

131.

132.2个野人去,完成 */ 

 

你可能感兴趣的:(include,2,closed,用,传教士)