用5个猜测解决MasterMind的Knuth算法

时间:2013-12-06 07:22:25

标签: c# algorithm

我读了knuth的算法in wikipedia,我想知道第3步。如果我理解每个选项的正确性(即使在步骤2中没有删除),我们计算每个ffedback可以删除多少可能的猜测。对于那一步,我们采取最低限度之后,我们在最小值上找到最大值并获取最大值所属的代码。这将是我们的第二个猜测。我不确定接下来可以做什么,因为每次我们不改变最小值的最大值(或最小值)。另外,我如何在c#中实现这一步骤。我该如何处理,如何实施该步骤?反馈的最小值真正意味着什么?

1 个答案:

答案 0 :(得分:5)

您需要不断收集所有可能的结果,其余备选方案的集合,以及可以根据猜测和解决方案计算结果的方法。

首先,为相关域对象建模:

public class Outcome
{
    public int White { get; set; }
    public int Black { get; set; }
}

public class Combination
{
    // however you like to model this
}

然后,创建一个检查秘密猜测的方法:

public static Outcome Check(Combination guess, Combination solution)
{
    // your implementation
}

现在算法如下:

Outcome[] outcomes = new[] { new Outcome { White = 0, Black = 0 },
                             new Outcome { White = 1, Black = 0 },
                             // ... all other possibilities
                            };

// assume we have some list of combinations
int min = Integer.MaxValue;
Combination minCombination = null;
foreach (var guess in combinations)
{
    int max = 0;
    foreach (var outcome in outcomes)
    {
        var count = 0;
        foreach (var solution in combinations)
        {
            if (Check(guess, solution) == outcome)
                count++;
        }
        if (count > max)
            max = count;
    }
    if (max < min)
    {
        min = max;
        minCombination = guess;
    }
}

在循环结束时,minCombination是您的下一个猜测。

编辑我在第一个版本中搞砸了min和max,现在已经修复了。如果选择combination和假设outcome,内部计数将提供剩余选项的数量。我们希望结果的最大值(所选combination的最差可能结果是剩下大多数选项的结果)。之后我们希望组合的最小值(最好的组合是在最坏的情况下留下最少选项的组合)。

如果您喜欢Linq,您也可以将算法编写为

combinations.MaxBy(guess =>
        outcomes.Min(outcome =>
                combinations.Count(solution => 
                        Check(guess, solution) == outcome)));

我使用MoreLinq project中的MaxBy