面对在国际象棋比赛中实施极小极大的性能问题

时间:2015-07-03 19:34:01

标签: java performance recursion artificial-intelligence minimax

我正在尝试为一个小型国际象棋游戏实施minimax算法。也许我的前提是错误的,这不是应该尝试的东西。是吗?

该计划有效,但存在很大的性能问题:

  • 深度= 0,1或2,结果立竿见影。
  • 深度= 3,结果需要15秒。
  • 深度= 4 - 尚未得到结果。

这是我的实施:

private Move findBestMove(Chessboard chessboard, int depth,
        boolean maximizingPlayer) {
    if (depth == 0) {
        return new Move(chessboard.calculateHeuristicValue());
    } else {
        Move bestMove;
        if (maximizingPlayer) {
            bestMove = new Move(Integer.MIN_VALUE);
            for (Move possibleMove : findAllPossibleMoves(chessboard,
                    !(maximizingPlayer ^ whiteTurn))) {
                Move move = findBestMove(
                        possibleMove.getResultChessboard(), depth - 1,
                        !maximizingPlayer);
                if (move.getValue() > bestMove.getValue()) {
                    possibleMove.setValue(move.getValue());
                    bestMove = possibleMove;
                }
            }
        } else {
            bestMove = new Move(Integer.MAX_VALUE);
            for (Move possibleMove : findAllPossibleMoves(chessboard,
                    !(maximizingPlayer ^ whiteTurn))) {
                Move move = findBestMove(
                        possibleMove.getResultChessboard(), depth - 1,
                        !maximizingPlayer);
                if (move.getValue() < bestMove.getValue()) {
                    possibleMove.setValue(move.getValue());
                    bestMove = possibleMove;
                }
            }
        }
        return bestMove;
    }
}

可能在算法的实现或对象的设计或其使用中存在错误。我不能把手指放在上面。所以,我想确保在尝试优化代码或调整程序的内存配置之前,我没有遇到任何重大问题。

注意:没有内存分析经验。

1 个答案:

答案 0 :(得分:2)

在国际象棋中,有20种可能进行第一步(16名由棋子组成,4名由骑士组成)。

为简单起见,我们假设下一步行动也是如此。

  • 对于深度1,MinMax仅考虑20次移动。
  • 对于深度2,MinMax考虑20次移动和20次移动,400次可能移动,没问题。
  • 对于深度3,MinMax考虑20 ^ 3 = 8.000可能的移动。你的机器已经有15秒了。
  • 对于深度4,MinMax考虑20 ^ 4 = 160.000可能的移动。这将比前一个花费大约20倍......

只是搜索空间变得太大 - 它随着输入(深度)大小呈指数增长。时间复杂度为O(20 ^深度)。

但是,我们不必搜索所有空间来寻找真正好的动作。

Alpha-beta pruning是MinMax的流行优化。

如果这还不够,我会考虑切换到完全其他算法 - Monte Carlo Tree Search(使用UCT)。

移动数据库也可以提供帮助 - 而不是计算你已经准备好(预先计算好的)开局的第一步。

1997年击败卡斯帕罗夫的着名Deep Blue使用了它们,你可以查看它使用了什么here