猜猜是谁?最佳算法

时间:2014-09-29 14:38:51

标签: java algorithm

我正在制作一个程序来模仿提问的游戏,以便确定谁是秘密人员。

我只是坚持如何以最有效的方式对我的问题进行分类,角色有6种不同的属性,衬衫,头发,眼睛,微笑,头发,眼镜。

enter image description here

我已经为此编写了一个程序但是我的决策树效率太低,以至于它提出了大约10-30个问题。我的目标是找到一个介于6-10个问题之间的算法。

如果有帮助的话,我会提供我的老树,告诉你我在谈论什么,但我会根据你们的想法制作一个新树。

if (g.hairIsColor(Color.BROWN) && g.eyeIsColor(Color.HAZEL) &&
    g.isSmiling() && g.shirtIsColor(Color.GREEN) &&
    g.isWearingGlasses())
    a = "Emily";

if (g.hairIsColor(Color.BROWN) && g.shirtIsColor(Color.GREEN)) {
    if (g.eyeIsColor(Color.BLUE))
        a = "Alice";
    else if (g.eyeIsColor(Color.GREEN))
        a = "Frank";
    else if (g.eyeIsColor(Color.BROWN) && g.isWearingGlasses())
        a = "Bob";
    else if (g.eyeIsColor(Color.BROWN))
        a = "Dave"; // this might be an error for other brown hair
    else
        a = "Isabelle";
}
// NULL IT WAS EMILY FALSE

else if (g.hairIsColor(Color.BROWN) && g.shirtIsColor(Color.RED)) {
    if (g.eyeIsColor(Color.GREEN))
        a = "Philip";
    else if (g.eyeIsColor(Color.BLUE) && !g.isSmiling())
        a = "Wendy";
    else if (g.eyeIsColor(Color.BLUE) && g.isWearingGlasses()) 
        a = "Mallie";
    else if (g.eyeIsColor(Color.BLUE))
        a = "Nick";
    else if (g.eyeIsColor(Color.BROWN) && g.isWearingHat())
        a = "Robert";
    else if (g.eyeIsColor(Color.BROWN) && g.isSmiling())
        a = "Quinn";
}



else if (g.hairIsColor(Color.BLACK) && g.shirtIsColor(Color.BLUE)) {
    if (!g.isSmiling())
        a = "Carol";
    else if (g.isWearingHat())
        a = "Gertrude";
    else
        a = "Olivia";
}


else if (g.hairIsColor(Color.BROWN) && g.eyeIsColor(Color.BLUE))
    a = "Tucker";

else if (g.hairIsColor(Color.BROWN) && g.eyeIsColor(Color.BROWN))
    a = "Zander";

else if (g.hairIsColor(Color.BLOND) && g.shirtIsColor(Color.RED))
    a = "Henry";

else if (g.hairIsColor(Color.BLOND) && g.shirtIsColor(Color.BLUE))
    a = "Jack";

else if (g.hairIsColor(Color.BLACK) && g.eyeIsColor(Color.HAZEL))
    a = "Karen";

else if (g.hairIsColor(Color.BLACK) && g.isWearingHat())
    a = "Xavier";

else if (g.hairIsColor(Color.BLACK))
    a = "Ursula";

else if (g.hairIsColor(Color.RED) && g.shirtIsColor(Color.GREEN))
    a = "Yasmine";

else if (g.eyeIsColor(Color.BLUE))
    a = "Larry";

else if (g.isWearingHat())
    a = "Sarah";

else if (g.isSmiling())
    a = "Victor";

return a;

3 个答案:

答案 0 :(得分:2)

这是一个概率问题:使用二进制问题解决问题

回答问题的最有效方法是提出最接近50%/ 50%概率的问题。 例如,如果有半个女孩和半个男人在统计上问这个问题"它是男人吗?"是更好的选择。

因此,您可能希望每个问题可以测试所有可能的问题,并找到与剩下的人最接近50/50的问题。

I've found a good article that might help you

答案 1 :(得分:0)

从这个图表中可以确切地看出你是在问问题和获取数据。您主要显示哪些条件必须为真,而不是您用于确定这些值的过程。

解决方案可能是在每个问题之后检查剩余的答案,看看哪个变量最可能是真的并询问是否是。例如,在初始设置大小中,询问“该人是否在微笑?”如果它是真的,将消除四种选择,但如果不是真的,可能会消除更多。另一种方法可能是最有效地检查哪个答案可能是当前数据集的一半,例如“这个人戴眼镜”会消除一半的答案。在下一个问题中,可能是检查该人是否有蓝眼睛会消除剩余的一半。这对某些人来说效率较低,但总的来说效率总体上更高(如果你平均每次得到一半的结果,你平均得到大约五到六个问题的答案)。

答案 2 :(得分:0)

可以做的是在源代码中映射表。有很多方法可以做到这一点。我将使用一个简单的对象数组

首先我们定义一个数据结构

Object[] person = new Object {"Alice", Color.BROWN, Color.GREEN, Color.BLUE, Boolean.TRUE, Boolean.TRUE, Boolean.FAlSE};

我们看到在每个索引下我们代表Alice的一些属性  0 - 名字  1 - 头发  2 - 衬衫  3 - 眼睛  4 - 眼镜  5 - 微笑  6 - 帽子

如果我们坚持这个顺序,我们只能比较来自人的价值与猜测中的价值。

Object[] guess = Object[] {Color.BROWN, COLOR.RED, Color.HAZE, Boolean.TRUE, Boolean.TRUE.Boolean.TRUE};

所以我们应该做的是创建我们添加人员的模型。

  List<Object[]> model = createModel(); //This method add preson into list

  for(Object[] person: model) {

     for(int i = 1; i < person.length; i++) {
          if(person[i].equals[gues[i]) {
            //We share some attributes 

            if(i == person.length -1) {
              return person[0]; //We report the name 
            }
         }  else {
            break; /We break and go to another person from model. 
         }
     }
  }

在下一阶段,您可以使用适当的类实现替换对象数组。