使用IDDFS和GreedyBFS的食人族和传教士

时间:2012-03-24 11:27:26

标签: java algorithm artificial-intelligence river-crossing-puzzle

三个食人族和三个传教士必须过河。他们的船只能容纳两个人。如果食人族的数量超过传教士,在河的两边,传教士都遇到麻烦(我不会描述结果)。每个传教士和每个食人族都可以划船。六个人怎么能过河?

我找不到使用IDDFS(迭代加深深度优先搜索)和GreedyBFS(贪婪最佳优先搜索)来解决此问题的算法。如何解决这个问题的想法也会让我感到高兴。

编辑:

我在wiki上找到了IDDFS的算法:

IDDFS(root, goal)
{
  depth = 0
  repeat
  {
    result = DLS(root, goal, depth)
    if (result is a solution)
      return result
    depth = depth + 1
  }
}


DLS(node, goal, depth) 
{
  if (depth == 0 and node == goal)
    return node
  else if (depth > 0)
    for each child in expand(node)
      DLS(child, goal, depth-1)
  else
    return no-solution
}

但我无法弄清楚DLS()中的扩展(节点)应该在我的问题中完成。 这是我的Node类:

public class Node{
    //x-no of missionaries
    //y-no of cannibals
    //z-position of boat
    int x,y;
    boolean z;
    Node(int x,int y,boolean z){
        this.x=x;
        this.y=y;
        this.z=z;
    }
    public int getM(){
        return this.x;
    }
    public int getC(){
        return this.y;
    }
    public boolean getB(){
        return this.z;
    }
    public void setM(int x){
        this.x=x;
    }
    public void setC(int y){
        this.y=y;
    }
    public void setB(boolean z){
        this.z=z;
    }

}

我将不胜感激。

2 个答案:

答案 0 :(得分:4)

如何在没有算法的情况下解决它?你的模型很小,可以在没有任何编程的情况下解决,前两个食人族去另一边,然后其中一个用船回来并带另一个食人族另一方面,现在另外一侧有3个食人族,其中一个背部和两个传教士到另一边(现在2 c和2 m在另一边)。在这个时间里,一个c有一个m回来(首先是2 c和2 m),另一个是2 m到另一边(另一边有3 m,有一个c),只有另一侧的c回来并在另一侧带有两个c(另一侧有2 c和3 m),再一个c回来并将最新的c移到另一侧。

如何使用像DFS这样的算法来模拟它?创建一个有向图,有2 ^ 6个位置(所有可能的{1,2,3,4,5,6}子集),它们如果你可以通过使用可用的移动从一个位置到另一个位置相互关联。一些节点是死节点(一侧导致更多食人族的节点),您将从图中删除此节点,然后您的任务是检查是否有从节点0 {}到节点63的方法{1,2 ,3,4,5,6},可以通过BFS,DFS等多种方式解决。

答案 1 :(得分:4)

为了使用您提到的算法,您需要弄清楚问题的状态空间是什么。 状态是对问题情况的完整描述(无论是起始情况,最终情况还是中间情况)。诀窍是在状态中包含足够的信息,以便能够确定状态是否是问题的解决方案,如果不是,则接下来该做什么。在您的情况下,表示状态的一种可能方式是使用三个变量:整数 m 表示在河的起始端有多少传教士,整数 c 告诉我们有多少食人族在起始端,而布尔 b 告诉船在哪一边。给定(m,c,b)的值,您可以确定可以采取哪些可能的操作,以及这将带您到哪些其他状态。您提到的算法实际上是用于搜索这样一组连接状态的算法。