Java 如何使用alpha-beta修剪构建游戏树
我试图建立一个游戏树,我的游戏,以便找到我的下一步行动。 首先,Im使用递归算法构建树,然后,使用alpha-beta修剪算法找到最佳移动Im。 我想用alpha-beta剪枝来构建游戏树,以最小化游戏树的大小,但是我在编写算法时遇到了问题。 你能帮我把alpha-beta剪枝添加到扩展算法中吗 以下是展开算法:Java 如何使用alpha-beta修剪构建游戏树,java,tree,alpha-beta-pruning,Java,Tree,Alpha Beta Pruning,我试图建立一个游戏树,我的游戏,以便找到我的下一步行动。 首先,Im使用递归算法构建树,然后,使用alpha-beta修剪算法找到最佳移动Im。 我想用alpha-beta剪枝来构建游戏树,以最小化游戏树的大小,但是我在编写算法时遇到了问题。 你能帮我把alpha-beta剪枝添加到扩展算法中吗 以下是展开算法: public void expand(int depth) { expand++; if(depth > 0) {
public void expand(int depth)
{
expand++;
if(depth > 0)
{
this.children = new ArrayList<GameTreeNode>();
List<Move> possibleMoves = this.b.possibleMoves(this.b.turn);
ReversiBoard tmp = null;
for(Move m : possibleMoves)
{
TurnState nextState = (this.state == TurnState.PLUS ? TurnState.MINUS : TurnState.PLUS);
tmp = new ReversiBoard(this.b);
tmp.makeMove(m);
int nextTurn = (turn == PLAYER1 ? PLAYER2 : PLAYER1);
if(tmp.possibleMoves(nextTurn).isEmpty())
nextTurn = turn;
this.children.add(new GameTreeNode(tmp, nextState, m, nextTurn));
for(GameTreeNode child : children)
child.expand(depth - 1);
}
}
}
以下是alpha-beta修剪代码:
int alphaBetaMax( int alpha, int beta, int depthleft ) {
alphaBetaNum++;
if ( depthleft == 0 ) return this.b.evaluate();
for (GameTreeNode tree : this.children) {
bestValue = alphaBetaMin( alpha, beta, depthleft - 1 );
if( bestValue >= beta )
{
bestMove = tree.move;
return beta; // fail hard beta-cutoff
}
if( bestValue > alpha )
alpha = bestValue; // alpha acts like max in MiniMax
}
return alpha;
}
int alphaBetaMin( int alpha, int beta, int depthleft ) {
alphaBetaNum++;
if ( depthleft == 0 ) return -this.b.evaluate();
for ( GameTreeNode tree : this.children) {
bestValue = alphaBetaMax( alpha, beta, depthleft - 1 );
if( bestValue <= alpha )
{
bestMove = tree.move;
return alpha; // fail hard alpha-cutoff
}
if( bestValue < beta )
beta = bestValue; // beta acts like min in MiniMax
}
return beta;
}
public void summonAlphaBeta(int depth)
{
this.bestValue = alphaBetaMax(Integer.MIN_VALUE, Integer.MAX_VALUE, depth);
}
谢谢大家! 您有两个选择
您可以通过将expand方法转换为expanderturnmin和expanderturnmax方法来组合这两种算法,这两种方法都以alpha和beta值为参数。理想情况下,任何共享代码都会被放入第三种方法中,以保持代码干净。
这里有一些示例代码供您考虑。在本例中,我假设静态成员正在存储最佳移动
public int bestValue(Board board, int depth, int alpha, int beta, boolean aiPlayer) {
if (depth >= MAX_DEPTH || board.possibleMoves(aiPlayer).isEmpty()) {
return board.getValue();
} else {
for (Move move: board.possibleMoves(aiPlayer) {
int value = bestValue(board.makeMove(move), depth + 1, alpha, beta, !aiPlayer);
if (aiPlayer && value > alpha) {
alpha = value;
bestMove = move;
if (alpha >= beta)
break;
} else if (!aiPlayer && value < beta) {
beta = value;
bestMove = move;
if (beta >= alpha)
break;
}
}
return aiPlayer ? alpha : beta;
}
}
最佳初始移动由以下因素决定:
board.bestValueboard,0,Integer.MIN\u值,Integer.MAX\u值,true;
然后使用board.getBestMove
更优雅的解决方案是将alpha和beta值存储在树本身中。这非常简单:生成每个子节点后,更新当前节点中的值。然后,如果它们超出允许的范围,则可以停止生成子节点。这是更标准的方法,计算成本较低,但会使节点使用更多内存。
你提到的第一个选项正是我想要的,但是我在编写代码时遇到了一点困难,我不知道如何组合它们。你能给我一个代码的例子吗?好的,今天某个时候我会在我的答案中发布一些示例代码。