IT 2 – WS 2010/2011 – Übungsblatt 5 Abgabe: 7.1.2011 Beispiel 5.1 [Hanoi.java] In dieser Aufgabe soll der Lösungsweg für das Problem der „Türme von Hanoi“ berechnet werden. Dieses Problem besteht aus drei Stäben A, B und C, auf die mehrere gelochte Scheiben gelegt werden können, welche alle unterschiedlich groß sind (siehe Abb. unten). Zu Beginn liegen alle Scheiben auf Stab A, der Größe nach geordnet, mit der größten Scheibe unten und der kleinsten oben. Ziel des Spiels ist es, den kompletten Scheiben-Stapel von A nach C zu versetzen. Bei jedem Zug darf die oberste Scheibe eines beliebigen Stabes auf einen der beiden anderen Stäbe gelegt werden, vorausgesetzt, dort liegt nicht schon eine kleinere Scheibe. Folglich sind zu jedem Zeitpunkt des Spieles die Scheiben auf jedem Stab der Größe nach geordnet. Implementieren Sie die Klasse ue51.Hanoi mit der statischen Methode public static ArrayList<String> getHanoiSequence(int n), die den Lösungsweg für ein Problem der Größe n (=Anzahl der Scheiben auf Stab A) berechnet und die notwendigen Bewegungen der Scheiben (in der richtigen Reihenfolge) als ArrayList ausgibt. Dabei werden die Bewegungen durch folgende Strings bezeichnet: "AB" … lege die oberste Scheibe von A auf B "AC" … lege die oberste Scheibe von A auf C "BA" … lege die oberste Scheibe von B auf A usw. Abb. „Türme von Hanoi“ Beispiel 5.2 [StringPermutations.java] Implementieren Sie die Klasse permutations.StringPermutations mit der statischen Methode static ArrayList<String> allStringPermutations(String[] array), die in einer ArrayList alle Strings zurückliefert, die durch Permutationen der übergebenen Strings gebildet werden können. In der ArrayList soll kein String doppelt vorkommen. Z.B. soll getAllPermutations({"aba","ab","a"}) eine ArrayList mit den Strings "abaaba", "abaaab", "ababaa", "aabaab", "aababa" (in beliebiger Reihenfolge) zurückliefern. -1- IT 2 – WS 2010/2011 – Übungsblatt 5 Beispiel 5.3 Gegeben ist folgendes Java Interface: interface Formula { int getLength(); boolean evaluate(boolean[] v); } Dabei gibt getLength() die Länge der Arrays an, die an evaluate() übergeben werden können. Schreiben Sie eine Methode boolean[] findSolution(Formula f), die ein boolean-Array ba der Länge f.getLength() zurückliefert, sodass f.evaluate(ba) den Wert true ergibt. Existiert ein solches Array ba nicht, soll null zurückgeliefert werden. Hinweis: Es müssen alle boolean-Arrays ausprobiert werden, bis ein passendes gefunden ist. Beispiel 5.4 Implementieren Sie in einer Klasse Packen die Methode boolean istPackbar(int[] gewichte, int maxAnzahl, int maxGewicht), die überprüft, ob die Gegenstände mit den in gewichte angegebenen Gewichten in maxAnzahl Kisten gepackt werden können, ohne dass in eine Kiste mehr als maxGewicht gepackt wird. Beispiel: Für gewichte={4,2,4,2,3} liefert istPackbar(gewichte,3,6)==true, istPackbar(gewichte,2,6)==false, und istPackbar(gewichte,3,5)==false. Beispiel 5.5 [Verteilung.java] Mehrere Aufträge sollen so auf zwei gleichartige Maschinen verteilt werden, dass die Aufträge möglichst schnell fertig gestellt werden. Dabei kann ein einzelner Auftrag nicht geteilt (also auf beiden Maschinen) bearbeitet werden. Schreiben Sie eine Klasse scheduling.Verteilung mit einem parameterlosen Konstruktor und der Methode public double optimaleBearbeitungszeit(double[] bearbeitungszeiten), die die optimale Gesamtbearbeitungszeit der Aufträge zurückliefert. Die Bearbeitungszeiten der einzelnen Aufträge werden der Methode in einem Array übergeben. Die Bearbeitungszeit auf einer Maschine ist die Summe der Bearbeitungszeiten der Aufträge, die dieser Maschine zugeteilt werden. Die Gesamtbearbeitungszeit der beiden Maschinen ist die größere Bearbeitungszeit der beiden Maschinen. Hinweis: Die Aufgabe kann mittels Exhaustive Search durch eine rekursive Methode gelöst werden. -2- IT 2 – WS 2010/2011 – Übungsblatt 5 Beispiel 5.6 Schreiben Sie eine Klasse Berechnung mit der Methode int f(int k), die für k ≥ 1 folgende Funktion f berechnet: • f(1) = 0. • Wenn k gerade, dann f(k) = f(k/2) + 1. • Wenn k ungerade, dann f(k) = f(3k−1) + 1. Die Klasse Berechnung soll weiters eine Methode boolean checkF(k,n) enthalten, die für k ≥ 1 true genau dann zurückliefert, wenn f(k) ≤ n. Die Methode checkF(k,n) soll auch dann false zurückliefern, wenn f(k) = +∞, d.h. wenn die Rekursion für f nicht terminiert. Das ist möglich, da die Rekursion für f evt. keinen Fortschritt in Richtung Basisfall macht. Hinweis: Die Methode checkF() kann, analog zur Methode f, recht einfach rekursiv implementiert werden. -3-