私はminimaxとalpha-betaプルーニングを使ってGomoku(16x16)のAIを構築していますが、非常に遅いです。これまでは、移動の順序を事前にソートしようとしましたが、ボードを深くコピーし、移動を追加して後で削除しました。また、私は検索ボードを減らすために、関連する動きのarraylistを使用しています(すでに配置されている部分の半径が2以内です)。しかし、AIはまだ3の深さ検索でも苦労しています。
編集:私は転置テーブルと呼ばれるものについて知りましたが、どこから始めるべきか分かりません。どんな助けも素晴らしいだろう!ここでGomoku AIのminimaxアルゴリズムを転置テーブルで改良しましたか?
private double minimax(Board node, String player, int depth, double lowerBound, double upperBound){
if (depth==3){
return node.evaluate();
}
if (player.equals(humanPiece)) {// min node
// sort setup
ArrayList<int[]> relevantMoves = node.relevantMoves();
HashMap<int[], Double> moveValueTable = new HashMap<>();
for (int[] move: relevantMoves){
node.addMove(move[0], move[1], player);
double val = node.evaluate();
moveValueTable.put(move, val);
node.retractMove(move[0], move[1]);
}
// insertion sort from small to big (alpha-beta optimization)
insertionSort(relevantMoves, moveValueTable);
result = Double.POSITIVE_INFINITY;
// minimax
for (int[] move : relevantMoves) { // y first, x second
node.addMove(move[0], move[1], player);
double score = minimax(node, node.getEnemy(player), depth+1, lowerBound, upperBound);
node.retractMove(move[0], move[1]);
if (score < upperBound) {
upperBound = score;
}
if (score < result) result = score;
if (lowerBound > upperBound) {
break;
}
}
return result;
}
else{// max node
// sort setup
ArrayList<int[]> relevantMoves = node.relevantMoves();
HashMap<int[], Double> moveValueTable = new HashMap<>();
for (int[] move: relevantMoves){
node.addMove(move[0], move[1], player);
double val = node.evaluate();
moveValueTable.put(move, val);
node.retractMove(move[0], move[1]);
}
// insertion sort from big to small (alpha-beta optimization)
reversedInsertionSort(relevantMoves, moveValueTable);
result = Double.NEGATIVE_INFINITY;
// minimax
for (int[] move : relevantMoves) { // y first, x second
node.addMove(move[0], move[1], player);
double score = minimax(node, node.getEnemy(player), depth+1, lowerBound, upperBound);
node.retractMove(move[0], move[1]);
if (score > lowerBound) {
lowerBound = score;
}
if (score > result) result = score;
if (lowerBound > upperBound) {
break;
}
}
return result;
}
}
このAIの事は一度も起こりませんでしたが、あなたはたくさんの 'addMove'と' retractMove'をやっているようですが、あなたは実際にはそれが見えるminとmaxesに興味があります。興味深い値を探すために一回のパスを行うすべての値の表を収集するのではなく、 –
@ M.Prokhorov私は分かりません。あなたは明確にすることができますか? –
遭遇するノードごとに、関連するすべての移動を2回繰り返します。私が提案したのは、この繰り返しを1回だけ行うことでした。これは残念なことに、あなたが「アルファベータ最適化」を行うことを禁じています。この最適化の有無にかかわらず、実際にコードをプロファイリングしましたか?助けてくれますか?あなたがそれを取り除くとどうなりますか? –