Spiele als Suchproblem • betrachten Spiele für zwei Personen, diese sind abwechselnd am Zug • Spiel endet in einem aus einer Menge möglicher Terminalzustände • deterministische, im Prinzip zugängliche Umgebung (perfect information), • allerdings können wegen des Aufwands evtl. nicht alle Zustände vorausberechnet werden (z.B. Schach: durchschnittlicher Verzweigungsfaktor b = 35, eine Partie besteht evtl. aus 50 Zügen → 35100 Zustände) d.h.: – müssen Heuristiken zur Bewertung von Nicht-Terminalknoten verwenden – Suche sollte tiefenbegrenzt erfolgen – Entscheidungen der Spieler können daher nicht perfekt sein • jeder Spieler nimmt von seinem jeweiligen Gegner an, dass dieser eine optimale Strategie spielt • Ergebniswerte für die beiden Spieler sind gleich mit entgegengesetztem Vorzeichen (zero-sum games) • Erweiterungen zu dieser restriktiven Form von Spielen denkbar: – mehr als zwei Spieler – Unzugänglichkeit (z.B. Kartenspiele) – zufällige Ereignisse Spiele als Suchproblem Game-Tree Search Grundlagen der KI (IF, AIF), Folie 1 Holger Langner, [email protected] Minimax-Algorithmus double Maximize( tNode node ) { IF( isTermNode(node) ) return utility(node); // -- bzw. IF( cutOffTest() ) return heuristic(node); v := -∞; FOR EACH sonNode OF node DO v:= max(v, Minimize(sonNode)); return v; } double Minimize( tNode node ) { IF( isTermNode(node) ) return utility(node); // -- bzw. IF( cutOffTest() ) return heuristic(node); v := ∞; FOR EACH sonNode OF node DO v:= min(v, Maximize(sonNode)); return v; } Minimax-Algorithmus Game-Tree Search Grundlagen der KI (IF, AIF), Folie 2 Holger Langner, [email protected] Eine Variante von Minimax: Negmax double Negmax( tNode node ) { max := -∞; IF( cutOffTest() ) { IF( maximizersMove() ) // -- kann z.B. durch Mitführen der aktuellen Tiefe // -- als Parameter für Negmax und Testen auf odd/eval // -- festgestellt werden return Eval(node); ELSE return -Eval(node); } FOR EACH son OF node DO { v:= -Negmax(son); IF( v > max ) max := v; } return max; } NegMax-Algorithmus Game-Tree Search Grundlagen der KI (IF, AIF), Folie 3 Holger Langner, [email protected] Minimax-Verfahren Aufruf in Entscheidungsfunktion, z.B. für Maximierer: tOperator DecideOnMove( tNode node ) { BestMoves = new PriorityQueue(); FOR EACH operator IN <OPERATORS APPLICABLE ON node> { sonNode := <Apply(operator, node)> snNode.operator := operator; BestMoves.SortedInsert(sonNode, Maximize(sonNode)); } return BestMoves.GetFirst().getOperator(); } → derartige Game-Tree Search-Verfahren sind brute-force Verfahren: es gewinnt i.A. derjenige Algorithmus, der die exakteste Heuristik verwendet und/oder aufgrund seiner Effizienz Züge am weitesten vorhersehen kann. → Pruning-Mechanismen zur Effizienzsteigerung Minimax allg. Game-Tree Search Grundlagen der KI (IF, AIF), Folie 4 Holger Langner, [email protected] Iteratives Vertiefen tPath IterativeDepthSearch( tNode start ) { FOR bound := 0 TO maxBound DO { path := BoundedDepthSearch(start, bound); IF( path != null ) return path; } } Tiefenbegrenzte Suche tPath BoundedDepthSearch( tNode start, int bound ) { Grey := new Stack(); Black := new LinkedList(); Grey.Push(start); WHILE( !Grey.Empty() ) { node := Grey.Pop(); Black.Insert(node); IF( isGoal(node) ) return ConstructPath(node); IF( node.depth < bound ) { FOR EACH son OF node { IF( !Grey.Contains(son) && !Black.Contains(son) ) { son.parent := node; son.depth := node.depth + 1; Grey.Push(son); } } } } return null; } Iteratives Vertiefen und Tiefenbegrenzte Suche Game-Tree Search Grundlagen der KI (IF, AIF), Folie 5 Holger Langner, [email protected] Alpha-Beta Pruning Ziel: zu einem möglichst frühen Zeitpunkt im Verlauf der Suche Teilbäume eliminieren, deren Terminalknoten unter Einbeziehung der Strategie des Gegners den Spielausgang nicht mehr beeinflussen können. double Maximize( tNode node, double alpha, double beta ) { IF( isTermNode(node) ) return utility(node); // -- bzw. IF( cutOffTest() ) return heuristic(node); FOR EACH sonNode OF node DO { alpha:= max(alpha, Minimize(sonNode, alpha, beta)); IF( alpha ≥ beta ) return beta; } return alpha; } double Minimize( tNode node, double alpha, double beta ) { IF( isTermNode(node) ) return utility(node); // -- bzw. IF( cutOffTest() ) return heuristic(node); FOR EACH sonNode OF node DO { beta:= min(beta, Minimize(sonNode, alpha, beta)); IF( beta ≤ alpha ) return alpha; } return beta; } Laufzeitbedarf: d/2 im best-case (wir durchmustern beginnend √ mit dem besten Knoten) O(b ) d.h. effektiver Verzweigungsfaktor vermindert sich auf b bzw.: wir können in derselben Zeit doppelt so tief suchen wie Minimax. → profitiert von Verfahren zum move-ordering Alpha-Beta Pruning Game-Tree Search Grundlagen der KI (IF, AIF), Folie 6 Holger Langner, [email protected]