【发布时间】:2015-01-17 13:00:39
【问题描述】:
我一直在尝试在我的 Mastermind 版本中实现 Knuth 的算法,但我在算法的第 6 步上有点卡住了。 Here is a link to the steps I'm using.(向下滚动一点)
这是从链接复制粘贴的第 6 步:
6 应用 minimax 技术找到下一个猜测,如下所示:对于每个 可能的猜测,即 1296 的任何未使用的代码,而不仅仅是那些 S,计算每个 S 中的可能性有多少被消除 可能的彩色/白色挂钩分数。猜测的分数是最低的 它可能从 S 中消除的可能性的数量。从集合中 得分最高的猜测,选择一个作为下一个猜测,选择 尽可能成为 S 的成员。 (Knuth 遵循 选择具有最小数值的猜测,例如2345更低 比 3456。Knuth 还举了一个例子,表明在某些情况下没有 S 的成员将是得分最高的猜测之一,因此 猜测不能在下一回合获胜,但有必要确保 赢得五场比赛。)
无论如何,每当我尝试执行第 6 步时,我的代码中的某处似乎都会出现问题。可能的组合数组越来越小(在关闭的第 9 回合增加到 8 个),但它的效率远没有达到应有的水平,因为该算法应该在 5 回合后正确猜测代码。我一直在环顾四周并检查 Stackoverflow 上的其他 Knuth 算法问题,但我在这些问题中找不到我的答案,所以我希望我能得到一些更直接的帮助。我基本上想知道的是哪里我的代码出现故障,为什么,以及如何解决它。任何答案将不胜感激!
这是我用来生成计算机将猜测的下一个(或第一个)代码的代码。
在此代码中,possibleCombList 用作我在步骤中描述的“S”版本,code 用作我当前/下一个猜测。
public void generateCode() {
ArrayList<String> bestGuesses = new ArrayList<String>(); // Create new
// array in
// which I
// store all
// the best
// guesses.
if (totalGuesses == 0) { // If this is the first guess, pick spot 1122
// from the array of combinations as my next
// code.
code = possibleCombList.get(1122);
}
else if (possibleCombList.size() == 1) { // If there's only one
// combination left in the
// array, pick that one.
code = possibleCombList.get(0);
}
else { // If none of the above are true, do this;
int tempBlackPins = 0;
int tempWhitePins = 0;
possibleCombList.remove(possibleCombList.indexOf(code)); // Remove
// last
// guess.
for (int i = 0; i < possibleCombList.size(); i++) { // (Step 5)
// Delete any
// code that
// would not
// give the same
// response if
// the last
// guess were
// the code.
for (int a = 0; a < 4; a++) {
if (possibleCombList.get(i).charAt(a) == (code.charAt(a))) {
tempBlackPins++;
} else if (possibleCombList.get(i).contains("" + code.charAt(a))) {
tempWhitePins++;
}
}
if (tempBlackPins != blackPins && tempWhitePins != whitePins) {
possibleCombList.remove(i);
}
}
int maxMinimum = 0;
for (int j = 0; j < possibleCombList.size(); j++) { // (Step 6)
// Apply minMax
// technique
// (calculate
// which codes
// would
// eliminate the
// most
// possibilities
// next turn and
// pick one of
// those codes).
int minimum = Integer.MAX_VALUE;
tempBlackPins = 0;
tempWhitePins = 0;
for (int i = 0; i < possibleCombList.size(); i++) {
for (int a = 0; a < 4; a++) {
if (possibleCombList.get(i).charAt(a) == (code.charAt(a))) {
tempBlackPins++;
} else if (possibleCombList.get(i).contains("" + code.charAt(a))) {
tempWhitePins++;
}
}
if (tempBlackPins != blackPins && tempWhitePins != whitePins) {
minimum++;
}
}
if (minimum == maxMinimum && minimum > 0) {
bestGuesses.add(possibleCombList.get(j));
}
if (minimum > maxMinimum) {
maxMinimum = minimum;
bestGuesses.clear();
bestGuesses.add(possibleCombList.get(j));
}
}
System.out.println(bestGuesses.size());
code = bestGuesses.get(0); // Grab position 0 of the array with best
// guesses and make that the next guess.
}
}
谢谢你们帮助我!
【问题讨论】: