Technische Universität Berlin Institut für Mathematik ADM I – Graphen und Netzwerkalgorithmen Sommersemester 2007 Prof. Dr. Stefan Felsner Felix König Elisabeth Günther Torsten Ueckerdt 2. Übungsblatt Abgabe: Freitag, 04.05.2007, vor der Übung Aufgabe 5 5 Punkte Beweist: In jedem Graphen gibt es einen Schnitt mit mindestens |E| 2 Kanten. (Tipp: Ein Schnitt entspricht einer Partition der Knotenmenge des Graphen in zwei Teilmengen. Man kann sich einen Greedy-Algorithmus überlegen, welcher einen Schnitt mit obiger Eigenschaft berechnet. Ein konstruktiver Beweis folgt daraus dann sofort.) Aufgabe 6 5 Punkte Sei G ein gerichteter Graph. Man definiert den Eingangs- und Ausgangsgrad eines Knotens v als δ − (v) := |{(w, v) ∈ E : w ∈ V }| und δ + (v) := |{(v, w) ∈ E : w ∈ V }|. a) Zeigt: In einem azyklischen gerichteten Graphen gibt es einen Knoten v mit δ − (v) = 0. b) Gebt einen Algorithmus als Pseudocode an, der eine topologische Sortierung der Knoten eines azyklischen gerichteten Graphen in Linearzeit berechnet und beweist seine Korretkheit und Laufzeit. Aufgabe 7 5 Punkte Beweist folgende Aussagen: a) In jedem zusammenhängenden nicht bipartiten Graphen gibt es einen Kreis ungerader Länge. b) In jedem stark zusammenhängenden nicht bipartiten Graphen gibt es einen gerichteten Kreis ungerader Länge. Aufgabe 8 5 Punkte Zeigt, das folgende drei Aussagen äquivalent sind: • G ist ein Baum. • G ist maximal kreisfrei. • G ist minimal zusammenhängend. Programmieraufgabe 1 Ziel dieser ersten Programmieraufgabe ist es, Klassen für die Arbeit mit Graphen zu entwickeln, welche alle Funktionalitäten bereitstellen, die für die Implementation der Graphenalgorithmen der ADM I notwendig sind. Ihr werdet diese Eure Graphenklassen das ganze Semester über in Programmieraufgaben benutzen. Da wir davon ausgehen, dass Ihr die Grundlagen des objektorientierten Designs in Java beherrscht, lassen wir Euch beim Klassendesign viel Freiheit - was gleichzeitig bedeutet, dass Ihr auch viel Verantwortung dafür tragt, wie schwer oder leicht Euch die Implementation von Algorithmen in den folgenden Programmieraufgaben fallen wird. Die Arbeitszeit, die man in ein gutes Design der grundlegenden Klassen steckt, spart man bei jeder Benutzung derselben aufs Neue ein... Teil 1: Abnahme während einer der RBs am Freitag, 04.05.2007 a) Entwerft und implementiert je eine Klasse für – einen gerichteten Graphen – seine Knoten – seine Kanten. Eure Klasse soll auch für Graphen mit wenigen Kanten speichereffizient sein, benutzt also keine Inzidenzmatrix. Beachtet, dass jeder Knoten und jede Kante unter Umständen Daten enthalten kann. Benutzt Generics, um für jede Anwendung den Typen dieser Daten spezifizieren zu können. Darüber hinaus verwalten viele Algorithmen so genannte Labels an Knoten und/oder Kanten. Diese Labels können nur einfache true/false Flags aber auch Listen von bestimmten Objekten sein. Benutzt also auch hier Generics, um Eurem Graphen größtmögliche Flexibilität mitzugeben. b) Schreibt eine Klasse, die in der Lage ist einen Graphen im folgenden Format aus einer Datei einzulesen und eine Instanz Eurer Graphenklasse daraus zu erzeugen: – die erste Zeile enthält die Anzahl n der Knoten des Graphen, – jede weitere Zeile enthält die Adjazenzliste eines Knotens - der Knotenindex (0, 1, . . . , n − 1) steht dabei am Anfang der Zeile, gefolgt von einem Doppelpunkt und einer Liste mit den Zielknoten, durch Semikola getrennt. Zum Beispiel: 2 5 0: 1: 2: 3: 4: 1; 3 2 0 1; 2; 4 2 0 1 4 3 Denkt dabei daran, dass Ihr hiervon später weitere Klassen werdet ableiten wollen, um erweiterte Formate mit Daten an Knoten und/oder Kanten lesen zu können. Trennt also die einzelnen Unterfunktionalitäten der Klasse (Knoten lesen, Kante lesen etc.) so sauber wie möglich, so dass sich einzelne von Ihnen später bei der Ableitung leicht überschreiben lassen. Schreibt für einen ersten kleinen Test eine Application oder ein Applet, von dem aus man einen Graphen aus einer Datei einlesen und sich seine Anzahl Knoten und Kanten ausgeben lassen kann. Dateien mit Graphen findet Ihr im zip-Archiv graphs.zip auf der Homepage. Dateien, deren Namen mit err anfangen, enthalten fehlerhafte Daten und sollen von Eurem Programm auch als solche erkannt werden. Teil 2: Abnahme während einer der RBs am Freitag, 11.05.2007 c) Testet Eure Graphenklasse. Schreibt hierzu eine Application oder ein Applet, welches zu einem Graphen aus einer Datei seine starken Zusammenhangskomponenten in Linearzeit bestimmt. Nummeriert dabei die einzelnen Komponenten und schreibt die entsprechende Nummer in das Datenfeld jedes Knotens und jeder Kante. Gebt das Ergebnis in möglichst übersichtlicher Form (aber ruhig als Text) aus. Sollten Euch bei der Bearbeitung dieses Punktes noch Unzulänglichkeiten des Designs Eurer Graphenklassen auffallen, nehmt Euch die Zeit diese zu beseitigen! Ihr werdet es Euch selbst in späteren Programmieraufgaben danken...