这个Java树如何快1000倍?

时间:2012-03-14 19:56:47

标签: java optimization heap

我正在为类似国际象棋的游戏编程AI,基于8 x 8网格上的两种类型的棋子。

我想构建一种minmax树,它代表游戏中的每一个可能的移动,首先是白人玩家,第二是黑人玩家。

我有这个generate()方法,它是递归调用的。我需要能够显示大约8个级别的可能移动。没有优化,这三个有8 ^ 8个叶子。

我实现了一个简单的系统,用于确定网格是否实际计算过,如果是这样的话,系统只是将子项指向计算中的子引用。

我不知道我的解释是否清楚,我将加入您应该能够理解的部分代码。

问题在于,实际上,我能够生成大约3或4个级别的所有可能性。我已经8岁了。

我希望能在不到5秒的时间内计算出来。

那么伙计们,您是否看到了优化算法的解决方案?

这是生成函数: leftDiagonalMove(),rightDiagonalMove()和frontMove()如果移动是非法的则返回false,或者如果移动是合法的则移动网格中的棋子并返回true。

clone()创建一个新实例,其具有与“parent”相同的属性,backMove()只返回上一次Move。

public void generate(Node root, boolean white, int index) {

    Grid grid = root.getGrid();

    Stack<Piece> whitePieces = grid.getPiecesByColor(WHITE);
    Stack<Piece> blackPieces = grid.getPiecesByColor(BLACK);
    Node node;

    String serial = "";
    // white loop
    for (int i = 0; i < whitePieces.size() && white; i++) {
        Piece wPiece = whitePieces.get(i);

        if (grid.leftDiagonalMove(wPiece)) {
            serial = grid.getSerial();
            if(!allGrids.containsKey(serial)){
                node = new Node(grid.clone());
                node.setMove(grid.getLastMove());
                root.addChild(node); // add modified grid
                allGrids.put(serial, node);
                //actualGrid.display();
                if (index < 5 && grid.getPosition(wPiece).x > 0)
                    generate(node, !white, index + 1);
                actualGrid.backMove(); // back step to initial grid
            }
            else{
                root.addChild(allGrids.get(serial));
            }
        }

        if (grid.frontMove(wPiece)) {
            // same code as leftMove
        }

        if (grid.rightDiagonalMove(wPiece)) {
            // same code as leftMove
        }

    }

    // black loop
    for (int i = 0; i < blackPieces.size() && !white; i++) {
        Piece bPiece = blackPieces.get(i);

        if (grid.leftDiagonalMove(bPiece)) {
            // same code as white loop and replacing wPiece by bPiece
        }

        if (grid.frontMove(bPiece)) {
            // same code as white loop and replacing wPiece by bPiece
        }

        if (grid.rightDiagonalMove(bPiece)) {
            // same code as white loop and replacing wPiece by bPiece
        }

    }

}

2 个答案:

答案 0 :(得分:3)

您需要在生成的AlphaBeta pruning移动中使用名为MinMax trees的内容。更多相关信息: http://en.wikipedia.org/wiki/Alpha-beta_pruning
http://www.progtools.org/games/tutorials/ai_contest/minmax_contest.pdf

基本上你做了一个级别的分支然后使用修剪你可以尽早消除坏分支。然后从未消除的分支中计算(对于每个)另一个级别。你再次修剪,直到达到所需的深度。

以下是您阅读minmax的更多链接:
1. http://en.wikipedia.org/wiki/Minimax
2. MinMax trees - when Min can win in two steps

这是关于优化国际象棋比赛的修剪:
1. http://en.wikipedia.org/wiki/Alpha-beta_pruning#Heuristic_improvements
2. http://en.wikipedia.org/wiki/Refutation_table#Related_techniques

答案 1 :(得分:0)

我不明白为什么在对元素进行随机访问时使用Stacks。通过使用Piece []数组,您可以获得较低的等级。