37
| | Pascal Schärli [email protected] 02.05.2018 Informatik II – Übung 9

Informatik II – Übung 9 - n.ethz.chpascscha/downloads/Slides 9.pdf · Pascal Schärli | 02.05.2018 | 4 Warm-Up (Basisprüfung 2012) Ein XY-Baum sei ein spezieller rekursiv definierter

Embed Size (px)

Citation preview

||

Pascal Schärli

[email protected]

02.05.2018

Informatik II – Übung 9

|| 02.05.2018Pascal Schärli 2

Was gibts heute?

Warm-Up

Nachbesprechung Serie 8

Best-Of Vorlesung:

– Minimax

– Alpha – Beta

Vorbesprechung Serie 9

Info zur Auffahrt

Warm - Up

|| 02.05.2018Pascal Schärli 4

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.

Zeichnet einen XY-Baum der Tiefe 3.

A

B

C

F

|| 02.05.2018Pascal Schärli 5

Warm-Up

Knotenin out

Baum Baum, )(

A

B

Z

-

...

outin

Baum:

Knoten:

A

B

EC

D

F

G

Der Baum H(I(J,K),(L,-))

– Kann mit dem Syntaxdiagramm generiert werden

– Ist ein XY Baum

Der Baum M(N(O,P),Q(R,-),S(T,U(V,W)))

– Kann mit dem Syntaxdiagramm generiert werden

– Ist ein XY Baum

Der Baum A(B(C(D,-),E),F(G,-))

– Kann mit dem Syntaxdiagramm generiert werden

– Ist ein XY Baum

Nachbesprechung

|| 02.05.2018Pascal Schärli 7

Nachbesprechung U8A1

Gegeben: [3, 7, 17, 25, 33, 47, 56, 62, 65, 66, 68, 70, 78, 89, 92]

|| 02.05.2018Pascal Schärli 8

Nachbesprechung U8A1

[3, 7, 17, 25, 33, 47, 56, 62, 65, 66, 68, 70, 78, 89, 92] - Aufteilung 1/3 2/3

|| 02.05.2018Pascal Schärli 9

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;

}…

}

|| 02.05.2018Pascal Schärli 10

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++; // IMeasureif (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);

}

|| 02.05.2018Pascal Schärli 11

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));}

}

… }

|| 02.05.2018Pascal Schärli 12

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)); }

|| 02.05.2018Pascal Schärli 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 < 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)); }

|| 02.05.2018Pascal Schärli 14

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)); }

|| 02.05.2018Pascal Schärli 15

Nachbesprechung U8A2

Messung Frage 1, Faktor: 2, mittlere Suchtiefe: 3.27Messung Frage 1, Faktor: 3, mittlere Suchtiefe: 3.40

Messung Frage 2, Faktor: 2, mittlere Suchtiefe: 4.74Messung Frage 2, Faktor: 3, mittlere Suchtiefe: 4.96

Messung Frage 3, Faktor: 2, mittlere Suchtiefe: 4.70Messung Frage 3, Faktor: 3, mittlere Suchtiefe: 3.90

|| 02.05.2018Pascal Schärli 16

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

|| 02.05.2018Pascal Schärli 17

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;

}

|| 02.05.2018Pascal Schärli 18

Nachbesprechung U8A4

20.- 15.- 10.- 5.-

5kg 3kg 1kg

values =

weights = 7kg

1000 1001 1010 1011 1100 1101 1110 11110000 0001 0010 0011 0100 0101 0110 0111

0000 0010 0100 0110 1000 1010 1100 1110

0000 0100 1000 1100

0000 1000

0000

0.- 5.- 10.- 15.- 15.- 20.- 25.- 30.- 20.- 25.- 30.- 35.- 35.- 40.- 45.- 50.-

maxWeight = 8kg

|| 02.05.2018Pascal Schärli 19

Nachbesprechung U8A4

1000 1001 1010 1011 1100 1101 1110 11110000 0001 0010 0011 0100 0101 0110 0111

0000 0010 0100 0110 1000 1010 1100 1110

0000 0100 1000 1100

0000 1000

0000

20.- 15.- 10.- 5.-

5kg 3kg 1kg

values =

weights = 7kg

0.- 5.- 10.- 15.- 15.- 20.- 25.- 30.- 20.- 25.- 30.- 35.- 35.- 40.- 45.- 50.-

maxWeight = 8kg

|| 02.05.2018Pascal Schärli 20

Nachbesprechung U8A4

1000 1001 1010 1011 1100 1101 1110 11110000 0001 0010 0011 0100 0101 0110 0111

0000 0010 0100 0110 1000 1010 1100 1110

0000 0100 1000 1100

0000 1000

0000

20.- 15.- 10.- 5.-

5kg 3kg 1kg

values =

weights = 7kg

0.- 5.- 10.- 15.- 15.- 20.- 25.- 30.- 20.- 25.- 30.- 35.- 35.- 40.- 45.- 50.-

Sobald wir wissen, dass ein Ast “zu schwer” ist,können wir ihn abschneiden!

maxWeight = 8kg

|| 02.05.2018Pascal Schärli 21

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 Astwithout.set(depth, false);Selection resultWithout = find(without, weight, values, weights, maxWeight);

if (weight + weights.get(depth) <= maxWeight) { //falls Ast “zu schwer” → AbschneidenSelection with = new Selection(depth + 1, selection.bits());//rechter Astwith.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;

}

|| 02.05.2018Pascal Schärli 22

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

|| 02.05.2018Pascal Schärli 23

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;

}}

}}return bestMove;

}

private int eval(GameBoard gb) {

return gb.countStones(myColor) - gb.countStones(Utils.other(myColor)); }

Vorlesung

|| 02.05.2018Pascal Schärli 25

Minimax

7

3 47

8 3 5 12107 4

8 10 3 2 12 7

MAX

MIN

MAX

MIN

|| 02.05.2018Pascal Schärli 26

Alpha/Beta – Beispiel an der Tafel

|| 02.05.2018Pascal Schärli 27

Alpha/Beta

7

3 57

8 3 587

8 3 2

MAX

MIN

MAX

MIN

-∞, ∞

-∞, ∞ -∞, 7

-∞, 7 8, 7

7, ∞

7, ∞ 7, 8

7, 8

α β – Pruning:

α – Best Möglicher Zug für MAX

β – Best Möglicher Zug für MIN

Falls α ≥ β → CUT

→ Wurzel hat immernoch den Wert 7

7, 8

7, ∞

7, ∞7, 5

7, 5

β

α

|| 02.05.2018Pascal Schärli 28

Alpha/Beta – Beispiel an der Tafel

|| 02.05.2018Pascal Schärli 29

Alpha/Beta – Super Seite fürs üben:

Alpha-Beta Pruning Practice

Computer Science Game Trees

Beispiele als PDF

Vorbesprechung

|| 02.05.2018Pascal Schärli 31

U9A1 - Spieltheorie

Tiefe?

Minimax → Bester Zug für Max

Optimale Strategie für Max(Für jeden Max-Knoten den besten Zug bestimmen)

α-β-Methode

|| 02.05.2018Pascal Schärli 32

U9A2 –

Minimax Spieler:

Konfigurierbare Suchtiefe

Bewertungsfunktion wieder die Differenz der Spielsteine

|| 02.05.2018Pascal Schärli 33

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.

|| 02.05.2018Pascal Schärli 34

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

|| 02.05.2018Pascal Schärli 35

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 ;)

U9A2 –

|| 02.05.2018Pascal Schärli 36

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

Auffahrt

|| 02.05.2018Pascal Schärli 37

Viel Spass!