如何在Java中加速minimax算法?

时间:2016-04-29 17:56:24

标签: java algorithm minimax

我正在试图弄清楚如何提高此算法的速度。它适用于两个游戏(2人游戏,CPU与人类游戏),但问题是当我分配超过三个堆(包含多个宝石,因此每个玩家可以拿起多个游戏),计算机播放器需要永远来计算动作:

public Object[] minimax(int depth, int player) {

        if(hasPlayer1Won(player)){
            return new Object[]{get_default_input(1),1};
        }else if(hasPlayer2Won(player)){
            return new Object[]{get_default_input(1),-1};
        }
        List<T> movesAvailable = getNextStates();

        if(movesAvailable.isEmpty()){
            return new Object[]{get_default_input(0), 0};
        }
        int min = Integer.MAX_VALUE;
        int max = Integer.MIN_VALUE;
        T computersMove = getNextStates().get(0);
        int i = 0;
        for (T move: movesAvailable) {
            makeAMove(move, player);
            Object[] result = minimax(depth + 1, player == G.PLAYER1 ? G.PLAYER2 : G.PLAYER1);
            int currentScore = (int)result[1];

            if(player == G.PLAYER1){
                max = Math.max(currentScore, max);

                if(currentScore >= 0 && depth == 0) {
                    computersMove = move;
                }
                if(currentScore == 1){
                    resetMove(move);
                    break;
                }
                if(i==movesAvailable.size() - 1  && max < 0){
                    if (depth == 0){
                        computersMove = move;
                    }
                }
            }else{
                min = Math.min(currentScore, min);
                if(min == -1) {
                    resetMove(move);
                    break;
                }
            }
            i++;
            resetMove(move);
        }

        return new Object[]{computersMove, player == G.PLAYER1 ? max: min};
    }

1 个答案:

答案 0 :(得分:1)

我已成功测试了以下改善极小极大的方法(用它来玩Tic-Tac-Toe和Domineering):

  1. Alpha beta pruning - 使用这种修剪的特殊变体,结合Lazy evaluation - 基本上不是生成整个树,而是在每一层上生成最佳移动并保持懒惰其他国家行动对的持有人(应用懒惰的评估方法,通过利用供应商并在不同于我所持有的移动时调用它)。

  2. Heuristic pruning - 请参阅该书中有关启发式的章节。我基本上只生成树的第一个d分支而不是确定性结果,我将该书中描述的启发函数应用于当前状态以确定启发式结果。每当移动(d + 1)时,我使用相同的方法生成另一个分支。 在这里,d是您选择的级别(最安全的方式是通过测试)

  3. Parallel computing也看一下这个,你可能会觉得实施起来比较困难但是还是有回报

  4. 前两个选项为我节省了大量的计算时间,这样我就能够以最佳5x5的方式玩Domineering,启发式最高可达10x10(根据你想要的程度,它可以更好)。