我在编写一个使用alpha-beta剪枝的Negamax算法。然而,只有在删除了”BAD”这一行代码后它才能正常工作,但我不知道为什么。我的代码是基于这个伪代码编写的。它正确吗?大多数实现会在一个循环中调用negamax(在一个单独的函数中处理根节点),我应该这样做吗?为什么?
private static double AlphaBetaWithMemory(Board board, int player, int depth, int max_depth, double alpha, double beta) { double eval = Double.NEGATIVE_INFINITY; List<Integer> moves; if (depth == max_depth || board.gameOver()) { double h = board.heuristic(player); return h; } else { movs=board.getMoves(); for (Integer m : moves) { if (depth == 1) { double val = -AlphaBetaWithMemory( board.move(m), (player + 1) % 2, depth + 1, max_depth, -beta, -alpha); if (val > eval) { best_mov = m; eval = val; } else if (val == eval) { if (Math.random() > 0.5) { best_mov = m; } } alpha = Math.max(alpha, val); //"BAD" LINE } else { double val = -AlphaBetaWithMemory( board.mover(m), (player + 1) % 2, depth + 1, max_depth, -beta, -alpha); eval = Math.max(eval, val); alpha = Math.max(alpha, val); if (alpha >= beta) { return beta; } } } } return eval;
回答:
问题出在:
else if (val == eval) { if (Math.random() > 0.5) { best_mov = m; }}
为了解决这个问题(并保持随机性),我只需要打乱”movs”的顺序。我知道对”movs”进行排序会更有效率。