使用二叉搜索树进行 Alpha Beta 修剪
Alpha Beta Pruning with Binary Search Tree
我正在使用找到的 Alpha-Beta 修剪示例研究 Minimax 算法 here。在示例中,他们使用数组来实现搜索树。我按照这个例子,但也尝试用二叉搜索树来实现它。以下是我在树中使用的值:3、5、6、9、1、2、0、-1。
最后的最佳值应该是 5。随着 BST 的实现,我一直得到 2。
我认为这是问题所在,但我不知道如何解决它:
如果它看到叶节点在尝试检查下一个值时停止获取空指针异常,我将代码写入 return 退出递归。但相反,我认为它过早地停止了搜索(基于我在使用调试器单步执行代码时看到的内容)。但是,如果我删除检查,代码将在空指针上失败。
有人能指出我正确的方向吗?我做错了什么?
代码如下:
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
您的问题是您的迭代取决于 2 的循环控制,而不是节点 == null 查找 nodeIndex.getRight()(for max) getLeft(for min.)[=11=]
记住一棵树有
1头(一级)
二级 = 2
第 3 级 = 4
4号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;
}
更改循环以正确控制迭代,您应该可以轻松找到最高值。
我正在使用找到的 Alpha-Beta 修剪示例研究 Minimax 算法 here。在示例中,他们使用数组来实现搜索树。我按照这个例子,但也尝试用二叉搜索树来实现它。以下是我在树中使用的值:3、5、6、9、1、2、0、-1。
最后的最佳值应该是 5。随着 BST 的实现,我一直得到 2。
我认为这是问题所在,但我不知道如何解决它:
如果它看到叶节点在尝试检查下一个值时停止获取空指针异常,我将代码写入 return 退出递归。但相反,我认为它过早地停止了搜索(基于我在使用调试器单步执行代码时看到的内容)。但是,如果我删除检查,代码将在空指针上失败。
有人能指出我正确的方向吗?我做错了什么?
代码如下:
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
您的问题是您的迭代取决于 2 的循环控制,而不是节点 == null 查找 nodeIndex.getRight()(for max) getLeft(for min.)[=11=]
记住一棵树有 1头(一级)
二级 = 2
第 3 级 = 4
4号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;
}
更改循环以正确控制迭代,您应该可以轻松找到最高值。