问题描述:设有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个野人去,完成 */