【问题标题】:Alpha Beta Pruning with Binary Search Tree使用二叉搜索树进行 Alpha Beta 修剪
【发布时间】:2018-10-14 15:54:44
【问题描述】:

我正在研究带有 Alpha-Beta Pruning 示例的 Minimax 算法 here。在示例中,他们使用数组来实现搜索树。我遵循了这个例子,但也尝试用二叉搜索树来实现它。以下是我在树中使用的值:3、5、6、9、1、2、0、-1。

最后的最佳值应该是 5。通过 BST 实现,我不断得到 2。

我认为这是问题所在,但我不知道如何解决它:
如果在尝试检查下一个值时看到叶节点停止获取空指针异常,我编写了代码以退出递归。但是相反,我认为它过早地停止了搜索(基于我在使用调试器单步执行代码时看到的内容)。如果我删除检查,代码会在空指针上失败。

有人能指出我正确的方向吗?我做错了什么?

代码如下:

public class AlphaBetaMiniMax {

    private static BinarySearchTree myTree = new BinarySearchTree();
    static int MAX = 1000;
    static int MIN = -1000;
    static int opt;

    public static void main(String[] args) {
        //Start constructing the game
        AlphaBetaMiniMax demo = new AlphaBetaMiniMax();

        //3, 5, 6, 9, 1, 2, 0, -1
        demo.myTree.insert(3);
        demo.myTree.insert(5);
        demo.myTree.insert(6);
        demo.myTree.insert(9);
        demo.myTree.insert(1);
        demo.myTree.insert(2);
        demo.myTree.insert(0);
        demo.myTree.insert(-1);

        //print the tree
        System.out.println("Game Tree: ");
        demo.myTree.printTree(demo.myTree.root);

        //Print the results of the game
        System.out.println("\nGame Results:");

        //run the  minimax algorithm with the following inputs
        int optimalVal = demo.minimax(0, myTree.root, true, MAX, MIN);
        System.out.println("Optimal Value: " + optimalVal);

    }

    /**
     * @param alpha = 1000
     * @param beta = -1000
     * @param nodeIndex - the current node
     * @param depth - the depth to search
     * @param maximizingPlayer - the current player making a move
     * @return - the best move for the current player
     */
    public int minimax(int depth, MiniMaxNode nodeIndex, boolean maximizingPlayer, double alpha, double beta) {

        //Base Case #1: Reached the bottom of the tree
        if (depth == 2) {
            return nodeIndex.getValue();
        }

        //Base Case #2: if reached a leaf node, return the value of the current node
        if (nodeIndex.getLeft() == null && maximizingPlayer == false) {
            return nodeIndex.getValue();
        } else if (nodeIndex.getRight() == null && maximizingPlayer == true) {
            return nodeIndex.getValue();
        }

        //Mini-Max Algorithm
        if (maximizingPlayer) {
            int best = MIN;

            //Recur for left and right children
            for (int i = 0; i < 2; i++) {

                int val = minimax(depth + 1, nodeIndex.getLeft(), false, alpha, beta);
                best = Math.max(best, val);
                alpha = Math.max(alpha, best);

                //Alpha Beta Pruning
                if (beta <= alpha) {
                    break;
                }
            }
            return best;
        } else {
            int best = MAX;

            //Recur for left and right children
            for (int i = 0; i < 2; i++) {

                int val = minimax(depth + 1, nodeIndex.getRight(), true, alpha, beta);
                best = Math.min(best, val);
                beta = Math.min(beta, best);

                //Alpha Beta Pruning
                if (beta <= alpha) {
                    break;
                }
            }
            return best;
        }
    }
}

输出:

Game Tree: 
-1 ~ 0 ~ 1 ~ 2 ~ 3 ~ 5 ~ 6 ~ 9 ~ 
Game Results:
Optimal Value: 2

【问题讨论】:

  • 你能发布一个包含输入的完整代码吗?
  • @kelalaka 我编辑了我的帖子以包含输入和输出。我想我可能已经找到了问题的一部分,但我仍然得到了 2 的值。我认为另一个问题是我认为对于每次运行,我都没有检查树的两边。我要么检查左边,要么检查右边——不是所有的孩子。不过,我仍在试图弄清楚如何解决它。

标签: java algorithm binary-search-tree minimax alpha-beta-pruning


【解决方案1】:

您的问题是您的迭代取决于 2 的循环控制,而不是 node== null 查找 nodeIndex.getRight()(for max) getLeft(for min.)

记住一棵树有 1头(一级)

第二级 = 2

第三级 = 4

4th 8 等等。因此,您的循环算法甚至不会下降 3 个级别。

for (int i = 0; i < 2; i++) {

     int val = minimax(depth + 1, nodeIndex.getLeft(), false, alpha, beta);
                best = Math.max(best, val);
                alpha = Math.max(alpha, best);

                //Alpha Beta Pruning
                if (beta <= alpha) {
                    break;
                }

更改循环以正确控制迭代,您应该很容易找到最高值。

【讨论】:

  • 这是有道理的。因此,我尝试了以下操作,而不是 for 循环:我在左侧节点上运行 miniMax() > 计算最佳 > 计算 alpha > 计算 beta 然后在右侧节点上执行 miniMax()。我的逻辑是做一些类似于树遍历打印的事情(递归调用 print(node.left) > 打印节点值 > 递归调用 print(node.right))。我仍然得到2。我至少在正确的轨道上吗?
  • 这是正确的,你需要一个遍历来找到 BST 的最小(最左侧节点)和最大(最右侧节点)使用将完全遍历树左侧和右侧的迭代一边寻找价值。是的,您在正确的轨道上,不要使用 for 循环来迭代树。这就是 nodeIndex.left 和 nodeIndex.right 或 getleft 和 getright 所做的。 en.wikipedia.org/wiki/Binary_search_tree 请使用链接更深入地解释 BST 树及其功能
  • 如果我帮助解决了您的问题,请将已回答的支票放在上面。
  • 我明白了!感谢您的帮助。
猜你喜欢
  • 2021-07-08
  • 1970-01-01
  • 1970-01-01
  • 2020-12-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-25
  • 2015-04-12
相关资源
最近更新 更多