IT 2 - WS 2016/2017 Übungsblatt 7 Abgabe: 27.1.2017 Beispiel 7.1

Werbung
IT 2 - WS 2016/2017
Übungsblatt 7
Abgabe: 27.1.2017
Beispiel 7.1 [freiwillig: RekursiveF.java]
Implementieren Sie die Klasse ueb81.RekursiveF mit einem parameterlosen Konstruktor und
der Methode
public int f ( int m , int n ) ,
die folgende Funktion f berechnet:
• f (m, n) = 0 wenn m ≤ 0 oder n ≤ 0,
• f (m, n) = f (m − 1, 2n) − f (m − 1, n) wenn m, n > 0 und n ungerade ist,
• f (m, n) = f (m, n/2) + m ∗ n wenn m, n > 0 und n gerade ist.
Implementieren in dieser Klasse weiters die Methode
public String [] allPrimes1000 () ,
die ein String-Array zurückgibt, das (in beliebiger Reihenfolge) genau alle Strings "(m,n)" mit
1 ≤ m, n ≤ 1000 enthält, für die f (m, n) eine Primzahl ist, z.B. also "(1,2)" und "(2,1)".
Beispiel 7.2 [* ParallelMergeSort.java]
Gegeben ist die Klasse parsort.geg.MergeSort mit einem parameterlosen Konstruktor und
den Methoden
public void sort ( int [] a , int start , int ende ) ,
public final void merge ( int [] a , int start , int mitte , int ende ).
Der Aufruf sort(a,start,ende) sortiert den Teil a[start],...,a[ende-1] des Arrays aufsteigend. Dabei muss 0 <= start <= ende <= a.length gelten.
Der Aufruf merge(a,start,mitte,ende) fügt die Elemente der bereits aufsteigend sortierten
Teile a[start],...,a[mitte-1] und a[mitte],...,a[ende-1] so zusammen, dass der gesamte Teil a[start],...,a[ende-1] aufsteigende sortiert ist. Dabei muss
0 <= start <= mitte <= ende <= a.length gelten.
(Hinweis: Das Schlüsselwort final bei der Methode merge() bedeutet, dass diese Methode in
einer Unterklasse nicht überschrieben werden kann.)
Schreiben Sie eine Unterklasse parsort.ParallelMergeSort von parsort.geg.MergeSort mit
dem Konstruktor
public Pa rallel MergeS ort ( int numThreads ).
In der Unterklasse soll die Methode sort() so überschrieben sein, dass sie beim Sortieren die
im Konstruktor angegebene Anzahl von Threads möglichst gut ausnutzt. Bei Verwendung von
4 parallelen Threads soll sich die Laufzeit mindestens halbieren, sofern genug Prozessoren zur
Verfügung stehen.
Eventuell wird es notwendig sein, im Paket parsort auch eine Unterklasse der Klasse Thread
zu definieren. Geben Sie diese gemeinsam mit der Klasse ParallelMergeSort ab.
Beispiel 7.3 [freiwillig: Versand.java]
Eine Anzahl von Produkten soll in Kisten verpackt werden. Dabei können höchstens 2 Produkte
in eine Kiste gepackt werden. Weiters darf die Summe der Gewichte der Produkte in einer Kiste
ein maximal zulässiges Gewicht nicht übersteigen. Alle Produkte sollen in die kleinstmögliche
Anzahl von Kisten verpackt werden.
Implementieren Sie die Klasse ueb43.Versand mit der Methode
public ArrayList < Kiste > einpacken ( ArrayList < Produkt > produkte ) ,
die eine Liste von Produkten in Kisten verpackt und die resultierende Liste von Kisten zurückgibt. In der Klasse global.Produkt ist eine Methode
public double getGewicht ()
implementiert, die das Gewicht des Produkts zurückgibt. In der Klasse global.Kiste gibt es
eine Methode
public static double getMaxGewicht () ,
die das maximal zulässige Gewicht für eine Kiste zurückgibt. Weiters gibt es zwei Konstruktoren, die ein oder zwei Produkte in eine Kiste packen und die resultierende Kiste zurückgeben:
public Kiste ( Produkt p ) ,
public Kiste ( Produkt p1 , Produkt p2 ).
Zum Beispiel könnten Produkte mit Gewichten 0.12, 0.14, 0.42, 0.83, 0.91, 1.00, 1.16, 1.27,
1.28, 1.33 bei einem maximal zulässigem Gewicht von 1.5 wie folgt optimal verpackt werden:
Kiste 1: 1.00, 0.42 Kiste 2: 1.16 Kiste 3: 0.14, 1.27 Kiste 4: 0.91 Kiste 5: 1.28, 0.12 Kiste 6:
0.83 Kiste 7: 1.33
Im Allgemeinen gibt es mehrere Möglichkeiten, die Kisten optimal zu packen.
Beispiel 7.4
Für diese Aufgabe werden Dominosteine als int-Arrays der Länge 2 dargestellt. Schreiben Sie
eine Klasse Anordnung mit der Methode
List < int [] > getAnordnung ( List < int [] > dominosteine ) ,
die eine Anordnung ergebnis aller übergebenen Dominosteine zurückgibt, sodass für
i=1,...,ergebnis.size()-2 eine Zahl von ergebnis.get(i) in ergebnis.get(i-1) und die
andere Zahl von ergebnis.get(i) in ergebnis.get(i+1) vorkommt. Wenn es keine solche
Anordnung gibt, dann soll die Methode null zurückgeben.
Beispiel: Die Anordnungen {3,4},{4,6},{6,1} und {3,4},{3,2},{4,2},{4,4} sind korrekt,
während es für die Dominosteine {3,4},{3,2},{3,1} keine korrekte Anordnung gibt.
Beispiel 7.5 [Lagerplanung.java]
Schreiben Sie eine Klasse ueb.Lagerplanung mit dem Konstruktor
public Lagerplanung ()
und der Methode
public int [] planen ( int anzBereiche , int anzPlaetze , int maxStuecke ,
int [] stueckArtikel )
die die Belegung eines Lagers berechnet. Das Lager besteht aus anzBereiche vielen identischen Bereichen, die jeweils über anzPlaetze viele Lagerplätze verfügen.
Die einzulagernden Artikel sind im Array stueckArtikel angegeben, wobei
stueckArtikel[i] angibt, wie viele Stück vom Artikel mit Nummer i eingelagert
werden sollen. Jedem Artikel soll ein Lagerbereich zugeordnet werden, also eine Nummer
0... anzBereiche-1. Einem Lagerbereich dürfen nicht mehr Artikel zugeordnet werden als
Lagerplätze vorhanden sind. Weiters dürfen in einem Lagerbereich insgesamt (summiert über
alle Lagerplätze) nicht mehr als maxStuecke viele Stücke gelagert werden.
Die Methode planen soll eine zulässige zuordnung von Artikeln zu Lagerbereichen zurückliefern, sodass zuordnung[i] den Lagerbereich angibt, der dem Artikel i zugeordnet ist. Gibt
es keine zulässige Zuordnung, so soll die Methode null zurückliefern.
Aufgabe 7.6 [Communicator.java] (Die Klasse wird automatisch geprüft.)
Schreiben Sie die Klasse threads.Communicator, die die Kommunikation zu Nachrichtenempfängern unterstützen soll. Das Interface threads.geg.Receiver mit der Methode
public void receive ( String message ) ,
ist gegeben. Diese Methode erlaubt es, eine Nachricht an einen Receiver zu senden. Die Klasse
Communicator soll über einen parameterlosen Konstruktor verfügen, sowie über die Methoden
public String signUp ( Receiver aReceiver ) ,
public void send ( String identifier , String message ) ,
public void sendAll ( String message ).
Die Aufrufe dieser Methoden aus mehreren Threads sollen vom Communicator synchronisiert
werden:
• Mit signUp(aReceiver) wird ein Receiver beim Communicator angemeldet. Die Methode liefert eine eindeutige Bezeichnung für den Receiver zurück. Ist der Receiver
schon angemeldet, dann wird wieder die zuvor vergebene Bezeichnung zurückgegeben.
• Durch send(identifier,message) soll message mittels aReceiver.receive(message)
an den durch identifier bezeichneten Receiver gesandt werden. Allerdings soll
aReceiver.receive(message) nur aufgerufen werden, wenn kein anderer Aufruf
send(identifier,message1) für diesen Receiver und kein Aufruf sendAll(message2)
aktiv ist. Falls ein solcher Aufruf aktiv ist, soll solange gewartet werden, bis
aReceiver.receive(message) durchgeführt werden kann.
Wenn identifier keine korrekte Bezeichnung ist, dann soll eine RuntimeException mit
dem Text "Invalid identifier!" geworfen werden.
• Mit sendAll(message) wird die Nachricht mittels aReceiver.receive(message) an alle
angemeldeten Receiver gesendet. Allerdings wird die Nachricht erst gesendet, wenn kein
anderer Aufruf sendAll(message1) und auch kein Aufruf send(identifier,message2)
aktiv ist. Solange die Nachricht nicht gesendet werden kann, soll gewartet werden.
Solange
ein
Aufruf
wartet,
soll
kein
send(identifier,message2) aktiv werden können (außer er ist schon aktiv).
sendAll(message)
Aufruf
Aufgabe 7.7
Gegeben sind
• die Klassen Layout und Produkt,
• die Klasse Fabrik mit dem Konstruktor
Fabrik ( Layout einLayout ) ,
der eine Fabrik mit dem angegebenen Layout erzeugt, und der Methode
Produkt fertige () ,
die eine Fertigung simuliert und das gefertigte Produkt zurückgibt,
• sowie folgendes Interface:
interface Zufallsgenerator
{
boolean istFehlerhaft ();
}
Implementieren Sie die Unterklasse FabrikMitFehlern von Fabrik mit dem Konstruktor
FabrikMitFehlern ( Layout einLayout , Zufallsgenerator zufall )
und überschreiben Sie die Methode fertige() so, dass null zurückgegeben wird, wenn
zufall.istFehlerhaft() als Ergebnis true liefert, und ansonsten das in der Oberklasse gefertigte Produkt.
Schreiben Sie auch eine Klasse Bernoulli, die Zufallsgenerator implementiert und über den
Konstruktor
Bernoulli ( double prob )
verfügt, sodass istFehlerhaft() mit Wahrscheinlichkeit prob als Ergebnis true liefert.
Herunterladen