我无法识别我的negamax(alpha-beta)实现中的错误。
我可以使简单的negamax版本工作正常,但我无法将其转换为其alpha-beta版本的negaMax。
首先是正在运行的简单的negaMax版本......
public class NegaMax {
static Node bestNode = null;
public static final Node getMove(Node root, boolean maximizingPlayer) {
bestNode = null;
int score = maximizingPlayer
? negaMax(root, 4, maximizingPlayer)
: negaMax(root, 4, !maximizingPlayer);
if(bestNode != null) {
bestNode.score = score;
}
return bestNode;
}
private static final int evaluate(Node node, boolean maximizingPlayer) {
return Integer.parseInt(node.value) * (maximizingPlayer ? 1 : -1);
}
private static final int negaMax(Node node, int depthLeft, boolean maximizingPlayer) {
if(depthLeft == 0) {
return evaluate(node, maximizingPlayer);
}
int max = Integer.MIN_VALUE;
Node bestChildSoFar = null;
List<Node> children = node.getChildren();
for(Node child : children) {
int score = -negaMax(child, depthLeft - 1, !maximizingPlayer);
if(score > max) {
bestChildSoFar = child;
max = score;
}
}
bestNode = bestChildSoFar;
return max;
}
...这里的版本不是......(返回-INFINITY) - (来自chessprogrammingwiki的源代码创意)......
public class AlphaBetaNegaMax {
public static final Node getMove(Node root, boolean maximizingPlayer) {
int score = maximizingPlayer
? alphaBeta(root, Integer.MIN_VALUE, Integer.MAX_VALUE, 4, maximizingPlayer)
: alphaBeta(root, Integer.MIN_VALUE, Integer.MAX_VALUE, 4, !maximizingPlayer);
System.out.println(score);
return null; // score is wrong ... fix this first
}
private static final int evaluate(Node node, boolean isMaximizingPlayer) {
return Integer.parseInt(node.value) * (isMaximizingPlayer ? 1 : -1);
}
private static final int alphaBeta(Node node, int alpha, int beta, int depthleft, boolean maximizingPlayer) {
if(depthleft == 0) {
return evaluate(node, maximizingPlayer);
}
List<Node> children = node.getChildren();
for(Node child : children) {
int score = -alphaBeta(child, -beta, -alpha, depthleft - 1, !maximizingPlayer);
if(score >= beta) {
return beta;
}
if(score > alpha) {
alpha = score;
}
}
return alpha;
}
}
答案 0 :(得分:1)
编辑:
问题是你没有抓住移动设置,整个4个深度移动设置,即最低移动设置为板上的每个部分深4个然后决定哪个用于最低成本的第一个移动设置,你只能找到最低的移动,在某些情况下可以是第二,第三或第四移动。如果返回该移动,则没有可能的方法来实际完成移动,因为您没有捕获到前面的移动板。
private static final int INF = Integer.MAX_VALUE;
private static final int DEPTH = 4;
private Move[] best4depthmove = new Move[DEPTH];
private int[] score4deep = new int[DEPTH];
public static final Move getMove(Move previous) {
for(int x = 0; x < DEPTH; x++)
{
best4depthmove[x] = null;
score4deep[x] = 0;
}
negamax(previous, 0);
return best4depthmove[0];
}
private static final negamax(Move move, int depth)
{
int newscore = 0;
if(depth < DEPTH)
{
List<Move> moves = Engine.getMoves(move);
for(Move m : moves)
{
newscore = MoveEvaluators.evaluate(m);
if(newscore > score4deep[depth])
{
score4deep[depth] = newscore;
best4depthmove[depth] = m;
}
negamax(m, depth+1);
}
}
}
这是我能想到的全部,它应该递归地完成每一个可能的动作。只要你有足够的内存容量来处理递归调用,这就可能适用于任何深度。
答案 1 :(得分:0)
我发现了这个错误,这个很微妙......问题是我假设Math.MIN_VALUE和Math.MAX_VALUE的绝对值都相同,忘记了java如何用2表示整数称赞
我刚刚将INFINITY定义为9999999,并将阳性和负无穷大都称为对称值,并且它起作用(alpha和beta的交换是这些值必须对称或我们看到这个错误的地方)
我认为网络上的这个小程序有一个类似的问题:http://ksquared.de/gamevisual/launch.php(我通知了作者,他回复说。他确实他有完全相同的错误!)