Informatik II Übung 9 pascscha@student.ethz.ch
Was gibts heute? Warm-Up Nachbesprechung Serie 8 Best-Of Vorlesung: Minimax Alpha Beta Vorbesprechung Serie 9 Info zur Auffahrt 2
Warm - Up
Warm-Up (Basisprüfung 2012) Ein XY-Baum sei ein spezieller rekursiv definierter Binärbaum: Der XY-Baum der Tiefe 0 ist der leere Baum. Der XY-Baum der Tiefe 1 ist ein Baum, der aus nur einem Knoten besteht Der XY-Baum der Tiefe n 2 besteht aus einem Wurzelknoten, dessen linker Nachfol-ger ein XY-Baum der Tiefe n 1 und dessen rechter Nachfolger ein XY-Baum der Tiefe n 2 ist. A Zeichnet einen XY-Baum der Tiefe 3. B F C 4
Warm-Up Baum: in Knoten out Der Baum H(I(J,K),(L,-)) Kann mit dem Syntaxdiagramm generiert werden Ist ein XY Baum ( Baum Der Baum M(N(O,P),Q(R,-),S(T,U(V,W))) Kann mit dem Syntaxdiagramm generiert werden Ist ein XY Baum, Baum ) Knoten: A in out B A Der Baum A(B(C(D,-),E),F(G,-)) Kann mit dem Syntaxdiagramm generiert werden Ist ein XY Baum... B C D F E G Z 5
Nachbesprechung
Nachbesprechung U8A1 Gegeben: [3, 7, 17, 25, 33, 47, 56, 62, 65, 66, 68, 70, 78, 89, 92] 7
Nachbesprechung U8A1 [3, 7, 17, 25, 33, 47, 56, 62, 65, 66, 68, 70, 78, 89, 92] - Aufteilung 1/3 2/3 8
Nachbesprechung U8A2 public class BinarySearch<Key extends Comparable<Key>, Value> implements IBinarySearch<Key, Value>, IMeasure { private int factor; private int numberofcalls; BinarySearch() { factor = 2; numberofcalls = 0; public void setfactor(int factor){ this.factor = factor; public int getnumberofcalls(){ return numberofcalls; 9
Nachbesprechung U8A2 public Value find(list<unit<key, Value>> haystack, Key needle) { numberofcalls = 0; return findrec(haystack, needle, 0, haystack.size()); private Value findrec(list<unit<key, Value>> haystack, Key needle, int begin, int end) { numberofcalls++; // IMeasure if (begin == end) { return null; int middle = begin + (end - begin) / factor; Unit<Key, Value> middlething = haystack.get(middle); int match = needle.compareto(middlething.key); if (match == 0) return middlething.value; else if (match < 0) return findrec(haystack, needle, begin, middle); else return findrec(haystack, needle, middle + 1, end); 10
Nachbesprechung U8A2 public class Measure { static final int[] keys = { 3, 7, 17, 25, 33, 47, 56, 62, 65, 66, 68, 70, 78, 89, 92 ; static ArrayList<Unit<Integer, Integer>> numbers; private static void createkeys() { numbers = new ArrayList<Unit<Integer, Integer>>(); for (int key : keys) { numbers.add(new Unit<Integer, Integer>(key, key)); 11
Nachbesprechung U8A2 private static void measure1(int factor){ BinarySearch<Integer, Integer> search = new BinarySearch<Integer, Integer>(); search.setfactor(factor); double result = 0; for (int key : keys) { search.find(numbers, key); result += search.getnumberofcalls(); result = result / keys.length; System.out.println(String.format("Messung Frage 1, Faktor: %d, mittlere Suchtiefe: %.2f",factor, result)); 12
Nachbesprechung U8A2 private static void measure2(int factor){ BinarySearch<Integer, Integer> search = new BinarySearch<Integer, Integer>(); search.setfactor(factor); double result = 0; for (int i = 0; i < 100; i++) { search.find(numbers, i); result += search.getnumberofcalls(); result = result / 100; System.out.println(String.format("Messung Frage 2, Faktor: %d, mittlere Suchtiefe: %.2f",factor, result)); 13
Nachbesprechung U8A2 private static void measure2(int factor){ BinarySearch<Integer, Integer> search = new BinarySearch<Integer, Integer>(); search.setfactor(factor); double result = 0; for (int i = 0; i < 10; i++) { search.find(numbers, i); result += search.getnumberofcalls(); result = result / 10; System.out.println(String.format("Messung Frage 3, Faktor: %d, mittlere Suchtiefe: %.2f",factor, result)); 14
Nachbesprechung U8A2 Messung Frage 1, Faktor: 2, mittlere Suchtiefe: 3.27 Messung Frage 1, Faktor: 3, mittlere Suchtiefe: 3.40 Messung Frage 2, Faktor: 2, mittlere Suchtiefe: 4.74 Messung Frage 2, Faktor: 3, mittlere Suchtiefe: 4.96 Messung Frage 3, Faktor: 2, mittlere Suchtiefe: 4.70 Messung Frage 3, Faktor: 3, mittlere Suchtiefe: 3.90 15
Nachbesprechung U8A3 Rucksackproblem - Gibt es immer genau eine optimale Lösung? Nein - Gegenbeispiel: Gewichte: 1, 2, 3 Werte: 1, 1, 2 maximales Gesamtgewicht: 3 erste Lösung: true, true, false zweite Lösung: false, false, true 16
Nachbesprechung U8A4 Brute Force public Selection findbest(arraylist<integer> values, ArrayList<Integer> weights, int maxweight) { if (values.size()!= weights.size()) throw new IllegalArgumentException("sizes of values and weights vectors are not equal"); final int max = 1 << values.size(); //max = 2^values.size() Selection bestselection = null; int maxvalue = -1; for (int i=0; i<max; i++) { Selection selection = new Selection(values.size(), i); if (selection.sum(weights) <= maxweight) { int value = selection.sum(values); if (value >= maxvalue) { bestselection = selection; maxvalue = value; return bestselection; 17
Nachbesprechung U8A4 values = weights = 20.- 15.- 10.- 5.7kg 5kg 3kg 1kg 0000 maxweight = 8kg 0000 1000 0000 0000 0100 0010 0100 1000 0110 1000 1100 1010 1100 1110 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111 0.- 5.- 10.- 15.- 15.- 20.- 25.- 30.- 20.- 25.- 30.- 35.- 35.- 40.- 45.- 50.- 18
Nachbesprechung U8A4 values = weights = 20.- 15.- 10.- 5.7kg 5kg 3kg 1kg 0000 maxweight = 8kg 0000 1000 0000 0000 0100 0010 0100 1000 0110 1000 1100 1010 1100 1110 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111 0.- 5.- 10.- 15.- 15.- 20.- 25.- 30.- 20.- 25.- 30.- 35.- 35.- 40.- 45.- 50.- 19
Nachbesprechung U8A4 values = weights = Sobald wir wissen, dass ein Ast zu schwer ist, können wir ihn abschneiden! 20.- 15.- 10.- 5.7kg 5kg 3kg 1kg 0000 maxweight = 8kg 0000 1000 0000 0000 0100 0010 0100 1000 0110 1000 1100 1010 1100 1110 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111 0.- 5.- 10.- 15.- 15.- 20.- 25.- 30.- 20.- 25.- 30.- 35.- 35.- 40.- 45.- 50.- 20
Nachbesprechung U8A4 public Selection findbest(arraylist<integer> values, ArrayList<Integer> weights, int maxweight) { if (values.size()!= weights.size()) throw new IllegalArgumentException("sizes of values and weights vectors are not equal"); Selection result = find(new Selection(0), 0, values, weights, maxweight); return result; private Selection find(selection selection, int weight, ArrayList<Integer> values, ArrayList<Integer> weights, int maxweight) { final int depth = selection.size(); if (depth == values.size()) return selection; Selection without = new Selection(depth + 1, selection.bits()); //linker Ast without.set(depth, false); Selection resultwithout = find(without, weight, values, weights, maxweight); if (weight + weights.get(depth) <= maxweight) { //falls Ast zu schwer Abschneiden Selection with = new Selection(depth + 1, selection.bits());//rechter Ast with.set(depth, true); Selection resultwith = find(with, weight + weights.get(depth), values, weights, maxweight); if (resultwith.sum(values) > resultwithout.sum(values)) return resultwith; return resultwithout; 21
Nachbesprechung U8A3 Test complex: Brute force: test took 127 milliseconds Backtracking: test took 13 milliseconds Backtracking ist viel schneller und findet trotzdem eine Optimale Lösung 22
Nachbesprechung U8A5 public Coordinates nextmove(gameboard gb) { Coordinates bestmove = null; int bestvalue = Integer.MIN_VALUE; for (int x = 1; x<=gb.getsize(); x++) { for (int y = 1; y <= gb.getsize(); y++) { Coordinates c = new Coordinates(x, y); if (gb.checkmove(mycolor, c)) { GameBoard hypotheticalboard = gb.clone(); hypotheticalboard.checkmove(mycolor, c); hypotheticalboard.makemove(mycolor, c); int value = eval(hypotheticalboard); if (value > bestvalue) { bestvalue = value; bestmove = c; private int eval(gameboard gb) { return bestmove; return gb.countstones(mycolor) - gb.countstones(utils.other(mycolor)); 23
Vorlesung
Minimax MAX 7 7 3 7 10 8 8 10 MIN 4 3 3 5 2 12 12 4 MAX 7 MIN 25
Alpha/Beta Beispiel an der Tafel 26
Alpha/Beta α β Pruning: -, α Best Möglicher Zug für MAX 3 -, 7 7 Wurzel hat immernoch den Wert 7 7, 7, 7 β Best Möglicher -, Zug für MIN Falls α β CUT MAX 7 8 -, 7 8 8, 7 β MIN 5 7, 7, 8 8 3 7, 8 3 7, 7, 5 7, 5 α 5 MAX 7, 8 2 MIN 27
Alpha/Beta Beispiel an der Tafel 28
Alpha/Beta Super Seite fürs üben: Alpha-Beta Pruning Practice Computer Science Game Trees Beispiele als PDF 29
Vorbesprechung
U9A1 - Spieltheorie Tiefe? Minimax Bester Zug für Max Optimale Strategie für Max (Für jeden Max-Knoten den besten Zug bestimmen) α-β-methode 31
U9A2 Minimax Spieler: Konfigurierbare Suchtiefe Bewertungsfunktion wieder die Differenz der Spielsteine 32
U9A2 Zeitmanagement: Begrenzte Spielzeit (Am Turnier 5 sek) Minimax-Analyse ständig mit grösserer Suchtiefe wiederholen bis Zeit fertig ist mit System.currentTimeMillis schauen ob man noch Zeit hat, sonst Exception werfen. 33
U9A2 private BestMove max(int maxdepth, long timeout, GameBoard gb, int depth) throws Timeout { if (time is up)... //abort //TODO: Abbruchbedingung mit maxdepth und depth => here you use eval()! for (all possible moves) clone board; make move; temp_move = min(maxdepth, timeout, cloned_board, depth+1); save in best_move if best move so far; return best_move Min-Funktion ist analog, nimmt aber schlechtesten Move! Die best bzw. worst Variable kann mit Integer.MIN_VALUE bzw. Integer.MAX_VALUE initialisiert werden 34
U9A2 Bessere Bewertungsfunktion eval() Mobility Wie viel Zugmöglichkeiten habe ich bzw. der Gegner? Ecken Ecken sind strategisch sehr wertvoll Anzahl Steine Zumindest am Anfang vom Spiel ist es meistens besser, möglichst wenige Steine zu haben. Am Schluss vom Spiel ändert sich das dann offensichtlich Gute Gewichtung durch trial and error herausfinden Wenn ihr bei der Run-Configuration -f anfügt werden die langsamen Animationen nicht mehr gemacht ;) 35
Auffahrt Nächste Woche ist Auffahrt es findet keine Übungsstunde statt. Ich werde die Folien trotzdem machen (mit extra Erklärungen) Ihr könnt am Mittwoch von 13 14 Uhr in eine andere Übungsstunde gehen (zb. im HG G 3 bei Vincent) Korrekturen ganz normal Nächste Lektion mit mir: 17.05.2018 36
Viel Spass! 37