Pascal Schärli 20.11.2020
Pascal Schärli 20.11.2020
Die Strategie ist schlechter, da die Suchtiefe im Durchschnitt grösser ist.
Pascal Schärli 20.11.2020
// 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;
}
Pascal Schärli 20.11.2020
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);
}
}
Pascal Schärli 20.11.2020
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));
}
}
Pascal Schärli 20.11.2020
// Suche nach allen vorhandenen Zahlen
private static void measure1(int factor) {
BinarySearch<Integer, Integer> search = new BinarySearch<Integer, Integer>();
search.setFactor(factor);
int sumCalls = 0;
for (int key : keys) {
search.find(numbers, key);
sumCalls += search.getNumberofCalls();
}
double result = ((double) sumCalls) / keys.length;
System.out.println(String.format("Messung Frage 1, Faktor: %d, mittlere Suchtiefe: %.2f", factor, result));
}
Messung Frage 1, Faktor: 2, mittlere Suchtiefe: 3.27 Messung Frage 1, Faktor: 3, mittlere Suchtiefe: 3.40
Pascal Schärli 20.11.2020
// Suche nach allen Zahlen von 0 bis 99
private static void measure2(int factor) {
BinarySearch<Integer, Integer> search = new BinarySearch<Integer, Integer>();
search.setFactor(factor);
int sumCalls = 0;
for (int i = 0; i < 100; i++) {
search.find(numbers, i);
sumCalls += search.getNumberofCalls();
}
double result = ((double) sumCalls) / 100;
System.out.println(String.format("Messung Frage 2, Faktor: %d, mittlere Suchtiefe: %.2f", factor, result));
}
Messung Frage 2, Faktor: 2, mittlere Suchtiefe: 4.74 Messung Frage 2, Faktor: 3, mittlere Suchtiefe: 4.96
Pascal Schärli 20.11.2020
// Suche nach allen Zahlen von 0 bis 9
private static void measure3(int factor) {
BinarySearch<Integer, Integer> search = new BinarySearch<Integer, Integer>();
search.setFactor(factor);
int sumCalls = 0;
for (int i = 0; i < 10; i++) {
search.find(numbers, i);
sumCalls += search.getNumberofCalls();
}
double result = ((double) sumCalls) / 10;
System.out.println(String.format("Messung Frage 3, Faktor: %d, mittlere Suchtiefe: %.2f", factor, result));
}
Messung Frage 3, Faktor: 2, mittlere Suchtiefe: 4.70 Messung Frage 3, Faktor: 3, mittlere Suchtiefe: 3.90
Pascal Schärli 20.11.2020
Pascal Schärli 20.11.2020
public class BruteForce implements IRucksack {
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 bestSelection = null;
int maxValue = -1;
final int max = (int) Math.pow(2, values.size());
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;
}
}
Pascal Schärli 20.11.2020
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());
without.set(depth, false);
Selection resultWithout = find(without, weight, values, weights, maxWeight);
if (weight + weights.get(depth) <= maxWeight) {
Selection with = new Selection(depth + 1, selection.bits());
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;
}
Pascal Schärli 20.11.2020
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;
}
Pascal Schärli 20.11.2020
Pascal Schärli 20.11.2020
6
6
2
9
8
9
5
2
7
9
5
3
4
6
7
3
7
Max
Max
Min
Min
Pascal Schärli 20.11.2020
6
9
\(\geq\)9
\(\leq\)6
Max
Min
Min
\([\ldots]\)
Da Min den Wert aller Kinder minimiert, muss dieser Knoten \(\leq 6\) sein
Da Max den Wert aller Kinder maximiert, muss dieser Knoten \(\geq 9\) sein
Da Min sowieso den Weg A wählen wird, müssen wir den Wert der restlichen Knoten nicht mehr auswerten
Weg A
Weg B
Pascal Schärli 20.11.2020
Pascal Schärli 20.11.2020
6
9
9
6
Max
Min
Min
\([- \infty, \infty]\)
Am Anfang gibt es noch keine Einschränkungen
\(\alpha = -\infty, \beta = \infty\)
Jetzt wissen wir, dass der Wert \(\leq 6\) ist.
\(\beta = 6\)
\([- \infty, 6]\)
\([- \infty, 6]\)
\([9, 6]\)
Wir wissen, der blaue Knoten hat einen Wert \(\geq 9\), daher gilt
\(\alpha = 9\)
Da \(\alpha \geq \beta\) müssen wir nicht mehr weiterrechnen
Pascal Schärli 20.11.2020
6
6
2
9
8
9
5
2
7
\(\geq\)8
5
3
4
6
7
\(\leq\)5
7
Max
Max
Min
Min
\([- \infty, \infty]\)
\([- \infty, \infty]\)
\([- \infty, \infty]\)
\([6, \infty]\)
\([-\infty, 6]\)
\([6, \infty]\)
\([6, \infty]\)
\([6, \infty]\)
\([6, \infty]\)
\([6, 5]\)
\([6, \infty]\)
\([6, 7]\)
\([6, 7]\)
\([8, 7]\)
\([6, \infty]\)
Pascal Schärli 20.11.2020
Pascal Schärli 20.11.2020
Pascal Schärli 20.11.2020
Pascal Schärli 20.11.2020
Pascal Schärli 20.11.2020
Minimax Algorithms
Pascal Schärli 20.11.2020
Minimax Algorithms
class BestMove {
/**
* The coordinates of the proposed next move
*/
public Coordinates coord;
/**
* The value of the proposed next move according to the min-max analysis
*/
public int value;
public BestMove(int value, Coordinates coord) {
this.value = value;
this.coord = coord;
}
}
Es könnte hilfreich sein, eine hilfs-Klasse zu schreiben, welche eure besten Züge speichert.
Pascal Schärli 20.11.2020
Zeitbegrenzung
Pascal Schärli 20.11.2020
Zeitbegrenzung
class Timeout extends Throwable {
private static final long serialVersionUID = 1L;
}
Erstellt eine eigene Exception, die ihr bei einem Timeout werfen könnt
Pascal Schärli 20.11.2020
Zeitbegrenzung
private BestMove max(int maxDepth, long timeout, GameBoard gb, int depth) throws Timeout {
if (time is up){
throw new Timeout();
}
if(depth == maxDepth){
//TODO: use eval() to determine the value of this position
}
for (all possible moves)
clone board;
make move on clone;
temp_move = min(maxDepth, timeout, cloned_board, depth+1);
save in best_move if best move so far;
return best_move
}
Die max-Funktion sieht in etwa so aus:
Pascal Schärli 20.11.2020
Bessere Bewertungsfunktion eval()
Pascal Schärli 20.11.2020
Pascal Schärli 20.11.2020