Ich baue eine KI für Gomoku (16x16) mit Minimax und Alpha-Beta-Beschneidung, aber es ist sehr langsam. Bis jetzt habe ich versucht, die Reihenfolge der Züge vorzusortieren und anstatt das Brett tief zu kopieren, die Züge hinzuzufügen und später zu entfernen. Außerdem benutze ich eine Arraylist von relevanten Moves (die sich in einem Radius von 2 zu bereits platzierten Stücken befinden), um das Suchboard zu verkleinern. Dennoch kämpft die KI immer noch bei einer Tiefensuche von 3.
Edit: Ich habe etwas über Transpositionstabelle herausgefunden, aber ich weiß nicht, wo ich anfangen soll. Jede Hilfe wäre großartig!Verbessern Minimax-Algorithmus für Gomoku AI mit Transposition Tabelle?
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;
}
}
Nachdem Sie diese AI-Sache noch nie gesehen haben, scheinen Sie eine Menge 'addMove' und' retractMove' zu machen, aber Sie interessieren sich tatsächlich für mins and maxes, wie es aussieht. Wie wäre es, statt eine Tabelle aller Werte zu sammeln, einen einzigen Pass zu machen, um nach interessanten Werten zu suchen? –
@ M.Prokhorov Ich verstehe es nicht. könntest Du das erläutern? –
Sie durchlaufen alle relevanten Züge zwei Mal für jeden Knoten, auf den Sie stoßen. Ich schlug vor, diese Iteration nur einmal zu machen. Dies verbietet dir leider, "Alpha-Beta-Optimierung" zu machen, was auch immer das ist. Haben Sie Ihren Code tatsächlich mit und ohne diese Optimierung profiliert? Hilft es? Was passiert, wenn Sie es entfernen? –