简体   繁体   中英

How to speed up minimax algorithm in Java?

I'm trying to figure out how to increase the speed of this algorithm. It works perfectly for two games (2-person games, CPU vs Human), but the problems is when I assign more than three piles (that contains a number of stones, so each player can pick up more than one), the computer player takes forever to compute the moves:

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};
    }

I have sucessfully tested the following methods for improving minimax (used it to play Tic-Tac-Toe and Domineering):

  1. Alpha beta pruning - used a special variant of this type of pruning, in conjunction with Lazy evaluation - basically instead of generating the whole tree I just generated an optimal move on each layer and kept Lazy holders for the other state-action pairs (applying the Lazy evaluation method, by making use of a supplier and calling it when a move different than the one I held was made).

  2. Heuristic pruning - see the chapter on heuristics in that book. I basically only generated the first d branches of the tree and instead of having a deterministic outcome, I applied the heuristic function described in that book to the current state to determine a heuristic outcome. Whenever move (d+1) was made, I generated another branch using the same approach. Here, d is the level that you choose (safest way is by testing)

  3. Parallel computing also have a look at this, you may find it harder to implement but it pays off

First 2 options brought me a lot of computational time save, such that I was able to play Domineering optimally up to a 5x5 board and heuristically up to 10x10 (it can be better depending on how well you want it to play).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM