Javaでチェッカーゲームのアルファベータプルーニングを使用してミニマックスを実装しようとしています。私のミニマックスアルゴリズムは完璧に機能します。私のコードは、アルファベータコードを使用して実行されます。残念ながら、標準のミニマックスアルゴリズムに対して1000ゲームをプレイすると、アルファベータアルゴリズムは常に50ゲーム程度遅れます。
アルファベータ法は動きの質を低下させるべきではないので、それらを達成するのにかかる時間だけで、何かが間違っている必要があります。ただし、ペンと紙を取り出し、仮想の葉ノード値を描画し、アルゴリズムを使用して、正しい最良の動きを計算するかどうかを予測しました。論理エラーはないようです。このビデオのツリーを使用しました:Alpha-BetaPruningを使用してアルゴリズムをトレースしました。論理的にはすべて同じ選択を行う必要があるため、機能する実装である必要があります。
また、コードにprintステートメントを追加しました(混乱を減らすために削除されています)。値は正しく返され、表示され、プルーニングが行われます。私の最善の努力にもかかわらず、私は論理エラーがどこにあるかを見つけることができませんでした。これは、これを実装するための私の3番目の異なる試みであり、それらすべてに同じ問題がありました。
ここに完全なコードを投稿することはできません。長すぎるため、エラーに関連するメソッドを含めました。確かではありませんが、問題は非再帰的なmove()メソッドにある可能性が高いと思いますが、論理的なエラーを見つけることができないので、もっとスラッシングして、おそらく何かを作っているでしょう韻や理由がなくても、良くなるよりも悪くなる。
forループの再帰呼び出しから複数の整数値を回復するためのトリックはありますか?それは私のミニマックスとネガマックスの両方の実装でうまく機能しますが、アルファベータ法はいくつかの奇妙な結果を生み出すようです。
@Override
public GameState move(GameState state)
{
int alpha = -INFINITY;
int beta = INFINITY;
int bestScore = -Integer.MAX_VALUE;
GameTreeNode gameTreeRoot = new GameTreeNode(state);
GameState bestMove = null;
for(GameTreeNode child: gameTreeRoot.getChildren())
{
if(bestMove == null)
{
bestMove = child.getState();
}
alpha = Math.max(alpha, miniMax(child, plyDepth - 1, alpha, beta));
if(alpha > bestScore)
{
bestMove = child.getState();
bestScore = alpha;
}
}
return bestMove;
}
private int miniMax(GameTreeNode currentNode, int depth, int alpha, int beta)
{
if(depth <= 0 || terminalNode(currentNode.getState()))
{
return getHeuristic(currentNode.getState());
}
if(currentNode.getState().getCurrentPlayer().equals(selfColor))
{
for(GameTreeNode child: currentNode.getChildren())
{
alpha = Math.max(alpha, miniMax(child, depth - 1, alpha, beta));
if(alpha >= beta)
{
return beta;
}
}
return alpha;
}
else
{
for(GameTreeNode child: currentNode.getChildren())
{
beta = Math.min(beta, miniMax(child, depth - 1, alpha, beta));
if(alpha >= beta)
{
return alpha;
}
}
return beta;
}
}
//Checks to see if the node is terminal
private boolean terminalNode(GameState state)
{
if(state.getStatus().equals(win) || state.getStatus().equals(lose) || state.getStatus().equals(draw))
{
return true;
}
else
{
return false;
}
}