用转置表改进Gomoku AI的minimax算法?

时间:2017-03-23 08:38:20

标签: java artificial-intelligence

我使用minimax和alpha-beta修剪为Gomoku(16x16)构建AI,但它非常慢。到目前为止,我已经尝试预先排序移动的顺序,而不是深度复制板,添加并稍后移除移动。此外,我使用相关移动的arraylist(在已经放置的片段的半径2范围内)来减少搜索板。然而,即使在3的深度搜索中,AI仍然在努力 编辑:我发现了一个名为换位表的东西,但我不知道从哪里开始。任何帮助都会很棒!

private double minimax(Board node, String player, int depth, double lowerBound, double upperBound){
    if (depth==3){
        return node.evaluate();
    }

    if (player.equals(humanPiece)) {// min node
        // sort setup
        ArrayList<int[]> relevantMoves = node.relevantMoves();
        HashMap<int[], Double> moveValueTable = new HashMap<>();

        for (int[] move: relevantMoves){
            node.addMove(move[0], move[1], player);
            double val = node.evaluate();
            moveValueTable.put(move, val);
            node.retractMove(move[0], move[1]);
        }
        // insertion sort from small to big (alpha-beta optimization)
        insertionSort(relevantMoves, moveValueTable);
        result = Double.POSITIVE_INFINITY;
        // minimax
        for (int[] move : relevantMoves) {  // y first, x second
            node.addMove(move[0], move[1], player);
            double score = minimax(node, node.getEnemy(player), depth+1, lowerBound, upperBound);
            node.retractMove(move[0], move[1]);
            if (score < upperBound) {
                upperBound = score;
            }
            if (score < result) result = score;
            if (lowerBound > upperBound) {
                break;
            }
        }
        return result;
    }

    else{// max node
        // sort setup
        ArrayList<int[]> relevantMoves = node.relevantMoves();
        HashMap<int[], Double> moveValueTable = new HashMap<>();

        for (int[] move: relevantMoves){
            node.addMove(move[0], move[1], player);
            double val = node.evaluate();
            moveValueTable.put(move, val);
            node.retractMove(move[0], move[1]);
        }
        // insertion sort from big to small (alpha-beta optimization)
        reversedInsertionSort(relevantMoves, moveValueTable);
        result = Double.NEGATIVE_INFINITY;
        // minimax
        for (int[] move : relevantMoves) {  // y first, x second
            node.addMove(move[0], move[1], player);
            double score = minimax(node, node.getEnemy(player), depth+1, lowerBound, upperBound);
            node.retractMove(move[0], move[1]);
            if (score > lowerBound) {
                lowerBound = score;
            }
            if (score > result) result = score;
            if (lowerBound > upperBound) {
                break;
            }
        }
        return result;
    }
}

1 个答案:

答案 0 :(得分:0)

以下是关于转置表如何工作的非常好的解释:TT

它可以通过从搜索树中删除转置来提高您的搜索速度。换位是可以通过两个或更多个不同的移动序列获得的位置。有些游戏,如国际象棋或西洋跳棋,有很多换位,有些则很少,甚至没有。

一旦你有了转置表,就可以轻松添加更多依赖它的速度优化。