【发布时间】:2018-05-26 01:37:28
【问题描述】:
import java.util.ArrayList;
import java.util.HashMap;
public class MiniMax {
public static final int SUGGESTIVE_MAX_DEPTH = 10;
public static int counter;
//AI (white), depth>0
public static int[] getComputerMove(Board b, int depth) {
ArrayList<ArrayList<Integer>> coloredMoves = b.getAllMoves(true);
int[] currentMove = new int[4];
int max = Integer.MIN_VALUE;
int[] bestMove = new int[4];
for (int k = 0; k < coloredMoves.size(); k++) {
ArrayList<Integer> a = coloredMoves.get(k);
for (int i = 2; i < a.size() - 1; i += 2) {
currentMove[0] = a.get(0);
currentMove[1] = a.get(1);
currentMove[2] = a.get(i);
currentMove[3] = a.get(i + 1);
int moveSetValue = min(b.simulateMove(currentMove), depth - 1, max, Integer.MAX_VALUE);
if (moveSetValue > max) {
max = moveSetValue;
bestMove = currentMove.clone();
}
}
}
System.out.println(counter);return bestMove;
}
//maximizer (white)
private static int max(Board b, int depth, int alpha, int beta) {
if (depth == 0 || Math.abs(b.getSum()) > 999990) { counter++;
return b.getSum();
}
ArrayList<ArrayList<Integer>> coloredMoves = b.getAllMoves(true);
for (int k = 0; k < coloredMoves.size(); k++) {
ArrayList<Integer> a = coloredMoves.get(k);
for (int i = 2; i < a.size() - 1; i += 2) {
int[] moveSet = new int[4];
moveSet[0] = a.get(0);
moveSet[1] = a.get(1);
moveSet[2] = a.get(i);
moveSet[3] = a.get(i + 1);
int moveValue = min(b.simulateMove(moveSet), depth - 1, alpha, beta);
alpha = (int) Math.max(alpha, moveValue);
if (alpha >= beta) {
return alpha;
}
}
}
return alpha;
}
//minimizer (black)
private static int min(Board b, int depth, int alpha, int beta) {
if (depth == 0 || Math.abs(b.getSum()) > 999990) {
counter++; return b.getSum();
}
ArrayList<ArrayList<Integer>> coloredMoves = b.getAllMoves(false);
for (int k = 0; k < coloredMoves.size(); k++) {
ArrayList<Integer> a = coloredMoves.get(k);
for (int i = 0; i < a.size() - 1; i += 2) {
int[] moveSet = new int[4];
moveSet[0] = a.get(0);
moveSet[1] = a.get(1);
moveSet[2] = a.get(i);
moveSet[3] = a.get(i + 1);
int moveValue = max(b.simulateMove(moveSet), depth - 1, alpha, beta);
beta = (int) Math.min(beta, moveValue);
if (alpha >= beta) {
return beta;
}
}
}
return beta;
}
}
我导入了 HashMap 但从未真正使用过它,所以这里没有转置表。我对极小极大的实现似乎真的很慢。我确实有一个评估函数,可以根据每块棋子的位置添加或删除价值,因此不应该有很多具有相同价值的棋盘状态。话虽如此,当我的计数器变量在深度 6 处停止在 ~27000 时,它会上升到数百万。我认为我正确地实现了 alpha beta 修剪,并且很难失败。但是,我认为在我这样做之后性能没有明显改善。
一些解释:
coloredMoves 获取所有可能的棋步。一次移动定义为移动块的坐标位置和该位置的坐标。
编辑:这里的深度是指每一个单独的动作。我是否可能高估了使用 minimax 进行 alpha beta 修剪的性能?网上显示它至少应该是 6。我的算法只在 4 深度的实际时间运行,这非常可悲。
【问题讨论】:
-
有人对此有答案吗?
-
为什么你认为深度六的 27000 是可以预期的?假设您处于起始位置,在 alpha-beta 修剪之前进入深度六有 119,060,324 个节点。将其降至几百万将是成功的。
-
如果你选择极小极大的负极大公式,我会更容易,因为代码重复。你在哪里读到你应该在正常时间内达到深度 6?
标签: java algorithm minimax alpha-beta-pruning