1 问题定义
河的两岸有三个传教士和三个野人需要过河,目前只有一条能装下两个人的船,在河的任何一方或者船上,如果野人的人数大于传教士的人数,那么传教士就会被野人攻击,怎么找出一种安全的渡河方案呢?
2 算法分析
首先,先来看看问题的初始状态和目标状态,定义河的两岸分别为左岸和右岸,设定状态集合为(左岸传教士人数,右岸野人数,右岸传教士人数,右岸野人数,船的位置),船的位置:-1表示船在左岸,1表示船在右岸。
初始状态:(3,3,0,0,0,-1)
目标状态:(0,0,3,3,1)
然后,整个问题就抽象成了怎样从初始状态经中间的一系列状态达到目标状态。问题状态的改变是通过划船渡河来引发的,所以合理的渡河操作就成了通常所说的算符,根据题目要求,可以得出以下5个算符(按照渡船方向的不同,也可以理解为10个算符):
渡1野人、渡1传教士、渡1野人1传教士、渡2野人、渡2传教士
根据船的位置,向左移或向右移通过递归依次执行5种算符,判断是否找到所求,并排除不符合实际的状态,就可以找到所有可能的解,如图1所示为递归函数流程图。
3 源代码
package joepa.javaweb;
import java.util.ArrayList;
import java.util.List;
public class River {
public static void main(String[] args) {
List lastParameters = new ArrayList();
List operation = new ArrayList();
RiverSides currentState = new RiverSides(3, 3, 0, 0, 1);
lastParameters.add(currentState);
cvsWdfs(currentState, lastParameters, operation, 0);
lastParameters.remove(lastParameters.size() – 1);
System.out.println(“执行完毕”);
}
private static int mycount = 0;// 统计成功过河次数
public static int cvsWdfs(RiverSides lastState,
List lastParameters, List operation,
int ifboacurrentStatety) {
if (lastState.getChurchR() == 3