传教士与野人渡河问题(使用C++解决)

       传教士与野人渡河的问题是人工智能类书中经常遇到的问题。书上的例子一般是3个传教士与3个野人,船上最多载2人。不过教我们这门课的老师布置作业让我们画出5个传教士与5个野人渡河,船上最多载3人。我以为很容易画出来的,结果越画越乱。最后决定使用C++写个程序,将搜索的过程表示出来。注:代码是在VS2017环境下编译运行的。

首先,设计三个表,在c++中我使用map 和vector 代替。分别是搜索表,用于存储当前搜索过的所有的状态;Open表,用于存储可被扩展的状态;Close表,用于存储被扩展的过的状态。搜索启发式是 f(n) = 传教士人数+野人人数-2*B+depth。其中船在左岸时B=1,否则B=0。depth表示当前状态在搜索图中的深度。为了能够看清当前搜索状态的信息,我定义了一个结构体:

typedef struct {
	int mission;	//左岸传教士人数
	int canver;		//左岸野人人数
	bool bank;		//true 船在左岸
	int depth;		//当前搜索的深度
	int id;			//唯一标识号
	int cost;		//当前的f(n) = M + C-2*B + depth
}Status;
其中存储的人数均为左岸的人数,id是状态的唯一标识,我定义了一个全局变量,当产生一个新的状态后,便自增1。三个表的定义如下:

	 	map<int, Status> Finding;		//保存当前正在搜索中的状态, <id号,status 结构体>
		map<int, int> Open;			//<id号, cost>
		vector<int> Close;		//close 表,保存id号
处理的函数包括:

判断当前状态是否合法,即两岸的野人数不可以多于传道士,但是可以有5个野人0个传教士等情况;

判断当前状态是否与已探索状态重复,通过比较左岸人数、船停靠的河岸是否相同判断;

判断当前是否为结果状态;

遍历Finding以及Open;

具体代码如下(注:当控制台显示过多内容的时候,最前

  • 2
    点赞
  • 48
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值