Informatik II - Übung 08 Christian Beckel beckel@inf.ethz.ch 17.04.2014 U7.A1: IFilter public ArrayList filterraw( ArrayList groups ) dynamic ArrayList result = new ArrayList(); cast for( int i = 0; i < groups.size(); i++ ) ArrayList group = (ArrayList) groups.get(i); for( int j = 0; j < group.size(); j++ ) Student student = (Student) group.get(j); if( filter( student ) ) result.add( student ); return result; Christian Beckel 17/04/14 2
U7.A1: IFilter public ArrayList<Student> filtergeneric(arraylist<arraylist<student>> groups) ArrayList<Student> result = new ArrayList<Student>(); for( int i = 0; i < groups.size(); i++ ) ArrayList<Student> group = groups.elementat(i); for( int j = 0; j < group.size(); j++ ) Student student = group.elementat(j); if( filter( student ) ) result.add( student ); return result; Christian Beckel 17/04/14 3 U7.A1: IFilter Helfermethode private boolean filter(student student) return student.getpoints() >= (IFilter.criteria / 100 * IFilter.maxNumberofPoints); Christian Beckel 17/04/14 4
For-each loop! Iteration über Arrays und Collections The core collections in Java http://download.oracle.com/javase/tutorial/collections/interfaces/index.html! Über alles, was das Iterable<E> Interface implementiert! Geht auch für eigene Datenstrukturen public ArrayList<Student> filtergeneric( ArrayList<ArrayList<Student>> groups ) ArrayList<Student> result = new ArrayList<Student>(); for(arraylist<student> group : groups ) for( Student student : group ) if( filter( student ) ) result.add( student ); return result; Christian Beckel 17/04/14 5 Beispiel for-each loop Equivalent for loop for( type var : arr ) //body of loop = for( int i = 0; i < arr.length; i++) type var = arr[i]; //body of loop for( type var : coll ) //body of loop = for( Iterator<type> iter = coll.iterator(); iter.hasnext(); ) type var = iter.next(); //body of loop leer! Christian Beckel 17/04/14 6
Bedingungen Although the enhanced for loop can make code much clearer, it can't be used in some common situations.! Only access. Elements can not be assigned to, e.g., not to increment each element in a collection.! Only single structure. It's not possible to traverse two structures at once, e.g., to compare two arrays.! Only single element. Use only for single element access, e.g., not to compare successive elements.! Only forward. It's possible to iterate only forward by single steps.! At least Java 5. Don't use it if you need compatibility with versions before Java 5. Christian Beckel 17/04/14 7 U7.A2 IBinarySearchTreeUtils! Typ T : Unbekannt, egal... public class TreeUtils<T> extends IBinarySearchTreeUtils<T> //... public int height(binarysearchtree<t> tree) if (tree == null) return 0; return 1 + Math.max(height(tree.left), height(tree.right)); //... Rest in Eclipse Christian Beckel 17/04/14 8
U7.A3 Random Player private Random rand = new Random(); //ausserhalb nextmove!!! public Coordinates nextmove( GameBoard gb ) Coordinates coord = null; ArrayList<Coordinates> validmoves = new ArrayList<Coordinates>( gb.getsize() * gb.getsize() ); System.out.print( "RandomPlayer" ); for( int row = 1; row <= gb.getsize(); row++ ) for( int col = 1; col <= gb.getsize(); col++ ) coord = new Coordinates(row, col); if( gb.checkmove( color, coord ) ) validmoves.add( coord ); if( validmoves.isempty() ) return null; int randindex = rand.nextint( validmoves.size() ); return validmoves.elementat( randindex ); Christian Beckel 17/04/14 9 Vorschau Übungsblatt 8 38 Punkte 2 Wochen Zeit Christian Beckel 17/04/14 10
Überblick 1) Binäre Suche (11 Punkte, Theorie & Praxis) 2) Tic-Tac-Toc-Spielbaum (5 Punkte) 3) Reversi: CheckMove() & Steine zählen 4) Rucksackproblem: Backtacking Christian Beckel 17/04/14 11 Zunächst: Datenstruktur Maps! Oft werden indizierte Daten benötigt! Personalien nach AHV-Nummer (unique id)! Dokumente nach Identifier (z.b. file name)! Dies wird möglich durch Maps! Identifier (Key) wird auf Inhalt (Value) "gemappt"! In der Java-Standardbibliothek! interface Map<Key extends Comparable<Key>, Value>! Implementationen: TreeMap, TreeMap,! Bsp.: Map<Integer, String> m = new HashMap<Integer, String>(); Christian Beckel 17/04/14 12
U8.A1: Binäre Suche " Binary Search Algorithm (illustrated) 3 4 9 15 17 22 23 24 27 28 32 34 37 38 40 41 " Entscheidungsbaum 15 # $ # 22 $ 17 23 24 query: 16 return: null query: 23 return: "23" Christian Beckel 17/04/14 13 U8.A1: Binäre Suche! Entscheidungsbaum zeichnen! Entscheidungsbäume übereinanderlegen Implementierung:! find(list<unit<key, Value>> haystack, Key needle)! setfactor(int factor)! Verallgemeinern der Suche $ nun auch unbalancierte Suchbäume! getnumberofcalls()! Benchmarking mit verschiedenen Faktoren! Durschnittliche Zahl (rekursiver) Aufrufe für verschiedene Faktoren Christian Beckel 17/04/14 14
U8.A2: Tic-Tac-Toe! Spielbaum zeichnen! Überlegt euch, wie das Attribut eines Knotens auf Basis der Attribute der Nachfolger berechnet wird, wenn Ihr bzw. der Gegner an der Reihe seid. Christian Beckel 17/04/14 15 U8.A3: Reversi (Teil 3) HumanPlayer RandomPlayer GreedyPlayer nextmove(): wartet auf Eingabe von der Kommandozeile nextmove(): wählt einen zufälligen (aber gültigen!) nächsten Zug nextmove(): wählt nächsten Zug anhand einer einfachen, nicht-rekursiven Bewertungsfunktion Download Übungsserie 7 Übungsserie 8 Christian Beckel 17/04/14 16
U8.A3: Reversi! Implementation von ICheckMove ohne das Framework! Ideen?! Implementieren eines Spielers, der unter allen möglichen Zügen den besten auswählt! Bester Zug: Zug, nach dessen Durchführung man maximal mehr Steine besitzt als der Gegner Christian Beckel 17/04/14 17 U8.A3: checkmove() boolean checkmove(gameboard gb, int player, Coordinates c) // Überprüfe alle Richtungen // Solange nicht mindestens eine Richtung gültig ist //... // GameBoard.checkMove darf nicht verwendet werden! Christian Beckel 17/04/14 18
U8.A3: greedyplayer()! Einfacher Computergegner! Denktiefe : 1 $ kein Spielbaum nötig!! Bewertungsfunktion: Unterschied der Steine nach dem Zug! Tipps! Ermitteln des besten Zugs 1) Board kopieren (ein GameBoard kann mit gb.clone() kopiert werden) 2) Einen möglichen Zug ausführen (Ihr dürft GameBoard.checkMove() hier verwenden) 3) Zählen (z.b. in Methode eval()) und besten Zug merken! Mit einer etwas intelligenteren Bewertungsfunktion schon ein ziemlicher Gegner Christian Beckel 17/04/14 19 U8.A4: Rucksackproblem und Backtracking x2 g2, w2 x3 g3, w3 x1 g1, w1 x4 g4, w4 x5 g5, w5 Christian Beckel 17/04/14 20
Rucksackproblem x1 g1, w1 x2 g2, w2 x3 g3, w3 x4 g4, w4! Problembeschreibung:! k Gegenstände x1,..., xk; Jeweils bekannter Wert und Gewicht! Auswahl von Gegenständen, so dass Gesamtgewicht nicht überschritten wird! Optimierungsproblem: Maximieren des Wertes der ausgewählten Gegenstände x5 g5, w5! Übungsblatt! Theorie! Bruteforce-Ansatz! Backtracking-Ansatz! Vergleich von Bruteforce und Backtracking Christian Beckel 17/04/14 21 Denken in Teilmengen!! Wie viele unterschiedlichen Möglichkeiten hat unser Dieb?! M = Menge der verfügbaren Gegenständen! Der Dieb kann nur eine Teilmenge davon nach Hause bringen! Der Dieb kann auch die leere Menge Ø (fauler Dieb) oder die gesamte Menge M (starker Dieb mit grossem Sack) schaffen!! Beispiel: Christian Beckel 17/04/14 22
Christian Beckel 17/04/14 23 Christian Beckel 17/04/14 24
Warum? Warum? Christian Beckel 17/04/14 25 U8.A4! Diebstrategie (zu implementieren) 1. Initialisierung 2. Nimm nächste Konfiguration (wie genau?) 3. Berechne das gesamte Gewicht if (gesamtes Gewicht < G) berechne Gesamtwert if (neuer Gesamtwert > Gesamtwert aktuelle optimale Lösung) aktuelle Konfiguration ist neue optimale Lösung 4. Falls noch Konfigurationen übrig, gehe zu Punkt 2 else Berechnung fertig! Liefert die Strategie das optimale Ergebnis?! Gibt es genau eine optimale Lösung? Christian Beckel 17/04/14 26
U8.A4 - Bitwertigkeit! Konfiguration als Bitfolge: class Selection! Die Bitwertigkeit bezeichnet den Stellenwert eines einzelnen Bits, den es durch seine Position innerhalb einer Binärzahl hat. Christian Beckel 17/04/14 27 U8.A4: Bruteforce ist einfach public Selection findbest(arraylist<integer> values, ArrayList<Integer> weights, int maxweight)... int last = java.math.pow(2, values.size()); //Anzahl der Teilmengen for( int i = 0; i < last; i++ ) new Selection(values.size(), i); //Selection Bitfeld mit Wert i...... Christian Beckel 17/04/14 28
U8.A4: Backtracking ist schwieriger! Klasse FindResult: Enthält Selection und Value! Rekursive Methode: FindResult fr = find(currselection, currweight, values, weights, maxweight);! Abbruchbedingung: selection.size() == values.size(); // alle Werte im Rucksack! In der Methode zwei mögliche Richtungen zum Weitergehen: //Gegenstand nicht mitnehmen... Selection without = new Selection(...); //um eins vergrössern, bit auf 0 setzen... //prüfen ob Gewicht passt, dann Gegenstand mitnehmen... Selection with = new Selection(...); //um eins vergrössern, bit auf 1 setzen...! In beiden Fällen rekursiver Aufruf (s.o.) Christian Beckel 17/04/14 29 U8.A4: Tipps! class Selection verstehen und verwenden!! Achtung: bei Vergrösserung der Konfiguration (neuen Gegenstand in den Sack legen) muss der neue Stellenwert initialisiert werden: new Selection(depth + 1, selection.bits()); Die neue Selection ist nun um ein Element größer und enthält den Inhalt der alten Selection. Christian Beckel 17/04/14 30
viel Spass! Christian Beckel 17/04/14 31