Prof. Dr. Detlef Krömker Jörg Demmer · Ashraf Abu Baker Robert-Mayer-Str. 10 60325 Frankfurt am Main Tel.: +49 (0)69 798-24610 Fax: +49 (0)69 798-24603 E-Mail: [email protected] [email protected] Fachbereich Informatik & Mathematik (12) Professur Graphische Datenverarbeitung Ausgabe: 22.11.2006 Abgabe: 01.12.2006 Vorlesung PRG-1, WS 06/07 – 6. Übung Zur Beachtung: Ab diesem Übungsblatt müssen Lösungen zu Programmieraufgaben getippt und per E-Mail beim Tutor abgegeben werden. Handgeschriebener Quellcode wird nicht mehr akzeptiert! Aufgabe 6.1: Binäre Suchbäume (2 Punkte) Ein binärer Suchbaum ist ein binärer Baum, bei dem Knoten mit kleineren Schlüsselwerten immer links und Knoten mit größeren Werten immer rechts eines Vorgängerknotens eingefügt werden. Beispielsweise ist der folgende Baum ein binärer Suchbaum: 5 3 2 7 4 6 Zeichnen Sie den binären Suchbaum, der entsteht, wenn die folgenden Eingabefolgen eingegeben werden: (a) 15, 6, 10, 25, 12, 3, 18, 1, 4, 30, 20, 16, 32, 8 (0,5 Punkte) (b) 1, 3, 4, 6, 8, 10, 12, 15, 16, 18, 20, 25, 30, 32 (0,5 Punkte) (c) Wenn ein Baum aufgebaut ist wie Baum (a) und n Knoten hat, wie lange müssen Sie im schlimmsten Fall suchen, um in diesem Baum einen Knoten zu finden oder zu wissen, dass er nicht existiert? Wie ist es beim Baum (b)? (1 Punkt) Aufgabe 6.2: Graphen (3 Punkte) Gegeben sei der folgende Graph: 1 a b 3 4 e c d 7 8 2 f g 5 Stellen Sie diesen Graphen dar: (a) in einer Adjazenzmatrix (1 Punkt) (b) in einer Inzidenzmatrix (1 Punkt) (c) in einer Adjazenzliste (1 Punkt) h 6 Aufgabe 6.3: Lerngruppenaufgabe: UML (5 Punkte) Tipp: UML wird im Reading Nr. 5 zur Vorlesung behandelt: http://www.gdv.informatik.unifrankfurt.de/lehre/ws2006/PRG-1/Readings/Guenther-Wahl-UML-Kompakt.pdf (a) Erläutern Sie kurz in eigenen Worten die Begriffe Aggregation, Assoziation und Komposition. Nennen Sie für jeden Begriff ein Beispiel, wie die entsprechende Beziehung zur Anwendung kommen kann. (1 Punkt) (b) Sie sollen für eine Einzelhandelskette ein Warenwirtschaftssystem programmieren, in dem Dinge wie Einkauf, Verkauf, Lagerhaltung, Logistik und Buchhaltung enthalten sind. Überlegen Sie sich Anwendungsfälle für ein solches System und stellen Sie sie in einem Use-Case-Diagramm in UML dar. (2 Punkte) (c) Erstellen Sie ein Klassendiagramm in UML aus dem folgenden Python-Code (2 Punkte): class aba: def __init__(self, a, b): self.__a = a self.b = b def geta(self): return self.__a def calc(self): return self.__a + self.b class bcb(aba): def __init__(self, a, b): aba.__init__(self, a, b) def doNothing(self, x): print "Really did nothing with " + str(x) class xyz: def __init__(self, x): # Prüft, ob x eine Instanz der Klasse bcb ist if isinstance(x, bcb): self.__x = x else: self.__x = None self.z = self.zzz() def doNothingWithbcb(self, x): self.__x.doNothing(x) class zzz: def __init__(self): pass def __helloWord(self): print "Hello, world!" Aufgabe 6.4: Bonusaufgabe: Bellman-Ford-Algorithmus (3 Punkte) In vielen Anwendungsbereichen (z.B. Logistik) ergibt sich die Notwendigkeit, in einem kantengewichteten Graphen kürzeste Wege von einem Knoten A zu einem Knoten B ermitteln zu können. Beispielsweise könnte man ein Wegenetz in einem solchen Graphen repräsentieren: K0 Hamburg 290 420 490 K3 Berlin 540 190 K1 Köln K2 Frankfurt 200 K4 Stuttgart 390 220 K5 München Kürzester Weg von Hamburg nach München? Wenn der Graph keine Zyklen mit negativer Länge enthält1 und die Knoten mit zunehmender Tiefe fortlaufend nummeriert sind, kann zur Lösung dieses Problems der (vereinfachte) Algorithmus von Bellman-Ford verwendet werden. Der Algorithmus findet den kürzesten Weg, indem iterativ ein Baum mit dem Startknoten als Wurzel konstruiert wird, in dem die Weglängen zu den einzelnen Knoten gespeichert sind. Jedem Knoten n des Baumes wird dabei die bislang zurückgelegte Weglänge I(n) zugeordnet und eine Markierung, ob der Knoten gestrichen ist oder nicht. Vorgehensweise: 1) Der Startknoten sei i0. Setze I(i0) = 0. Dann ist B der Baum, der nur aus dem Knoten i0 besteht, und die bislang zurückgelegte Wegstrecke ist natürlich 0. 1 Wäre z.B. der Fall, wenn der Graph eine Kante Frankfurt-Hamburg mit Wert -1000 enthielte. Dann könnte man eine Rundreise Hamburg-Köln-Frankfurt-Hamburg machen und dabei eine negative Zahl von Kilometern zurücklegen. In dem Fall funktioniert der hier vorgestellte Algorithmus nicht. 2) Wenn die Blätter von B keine unmittelbaren Nachfolger im Graphen mehr besitzen oder nur noch Nachfolger, die in B bereits gestrichen worden sind, beende die Verarbeitung. Sonst fahre fort mit Schritt 3. 3) Von einem Blatt i mit kleinster Tiefe (bei fortlaufender Nummerierung: Mit kleinster Knotennummer), das nicht ausschließlich gestrichene unmittelbare Nachfolger in B besitzt, betrachte in beliebiger Reihenfolge alle unmittelbaren Nachfolger j im Graphen. o Wenn j noch nicht in B enthalten ist, füge j in B als unmittelbaren Nachfolger von i hinzu und setze für die Wegstrecke I(j) = I(i) + cij (das Gewicht, mit dem die Kante zwischen i und j versehen ist). o Wenn j schon in B enthalten ist und es gilt I(i) + cij < I(j), dann markiere den vorhandenen Knoten j und sämtliche Nachfolger als gestrichen. Füge j als Nachfolger von i in den Baum ein und setze I(j) = I(i) + cij. o Wenn j schon in B enthalten ist und es gilt I(i) + cij > I(j), füge ihn als gestrichenen Nachfolger in den Baum ein. o Wenn j schon in B enthalten ist und es gilt I(i) + cij = I(j), dann füge in B j als Nachfolger von i hinzu, sofern j nicht schon auf dem Weg von i0 nach i vorhanden ist, und setze I(j) = I(i) + cij ; sonst füge j als gestrichenen Nachfolger ein. 4) Gehe zu Schritt 2, wenn alle unmittelbaren Nachfolger von i bearbeitet worden sind. (a) Wenden Sie das Verfahren an, um den kürzesten Weg von K0 nach K5 zu finden, und zeichnen Sie den konstruierten Wegebaum. (1 Punkt) (b) Implementieren Sie den Algorithmus in Python, und speichern Sie den Graphen und den zu konstruierenden Baum in einer geeigneten Datenstruktur. (2 Punkte) Hinweis: Die maximal erreichbare Punktzahl für dieses Übungsblatt beträgt 10 Punkte. Die Bonusaufgabe ist eine Möglichkeit, Punktverluste aus den anderen Aufgaben auszugleichen.