人工智能引论课第一次作业:使用搜索解决传教士与野人问题。
题目要求
河岸的一侧有野人与传教士各 m m m个,有一条能容纳 n n n个人的船。传教士与野人都会划船,现在要求任何情况下,野人数不能超过传教士数。设计一个程序,对于给定的 m , n m,n m,n,输出最少的划船次数。
输入数据
一行数据,为两个整数 m , n m,n m,n,中间用空格隔开,意义如上所述。其中 m ≤ 1000 , n ≤ 100. m \leq 1000, n\leq 100. m≤1000,n≤100.
算法分析
题目要求输出次数最优解,可以使用广度优先搜索。使用结构体描述当前状态,记录数据为左岸的野人数和传教士数,搜索深度以及船的位置情况。使用三维数组构建闭节点集,使用队列构建开节点集。
搜索时,从左岸向右岸,先从高到低循环船上人数,再循环野人或传教士数。同时,以下几种情形不合法:
- 左岸剩余野人和传教士均不为 0 0 0,且剩余的野人和传教士不相等,且左岸的剩余传教士不是全部。也就是说,要么左岸只有一种,要么相等。
- 船上有传教士,而且少于食人魔。
- 上船的循环变量大于左岸剩余人数。
右岸向左岸时类似。另外可以做的优化是:往左划,让一个野人划回去或者一个野人一个传教士。
使用结构体State
描述左岸的情况,成员如下:
struct State{
int c, m;//左岸野人与传教士数
int boat;//船在哪一边,1为左岸,0为右岸
int dep;//搜索深度,即划船次数
};
具体代码如下:
#include<queue>
#