6. Graphen
6.6 Programmierprojekt: Längste Pfade in DAGs
Im Englischen lassen sich schöne Wortketten bilden, in dem man in einem Wort einen Buchstaben rausstreicht und so wiederum ein neues Wort enthält. Hier ist ein Beispiel:
whines whine wine win in
Dies ist nicht die längste derartige Kette. In diesem Projekt wollen wir Java-Programme schreiben, die für eine gegebene Wortliste die längste derartige Kette finden. Als erstes müssen wir erkennen, dass es sich hier um ein Graphenproblem handelt. Was ist der Graph? Die Knoten sind die Vokabeln, und die gerichteten Kanten sind, naja, sehen Sie selbst:
Der vollständige Graph ist natürlich viel größer.
Übungsaufgabe
Schreiben Sie ein Programm ReadVocabularyDigraph.java
, das eine
Liste von Vokabeln einliest und daraus den "Lösche-einen-Buchstaben"-Digraphen baut.
Die Liste hat folgendes Format:
weaves eaves braver weave braver grave ave wave rave gave
Also einfach eine Liste von Vokabeln, eine pro Zeile, nicht notwendigerweise sortiert.
Ihr Programm soll ein Digraph
-Objekt wie in
Digraph.java erstellen.
Das Wort grave
soll zu einem Knoten mit dem Namen grave
und Raus-Nachbarn gave, rave, ...
und den Rein-Nachbarn
graves, gravel, ...
werden.
Ihr Programm die Anzahl der Kanten im Digraph ausgeben.
Testen Sie Ihr Programm auf der Vokabeldatei englishVocabulary.txt.
Übungsaufgabe
Schreiben Sie ein Programm DigraphNavigator.java
. Dieses soll von
System.in
einen Knotennamen lesen und dann, in zwei Zeilen, alle Raus-Nachbarn und Rein-Nachbarn
anzeigen, also
java DigraphNavigator < englishVocabulary.txt
grave
outNeighbors: rave, gave
inNeighbors: gravel, graves
grav
Error: couldn't find "grav" in file "englishVocabulry.txt
Ihr Programm soll noch zwei Sonderbefehle $max-in
und $max-out
haben, die Listen der Wörter mit maximalen In-Degree und Out-Degree ausgeben.
Übungsaufgabe Beschreiben Sie einen Algorithmus, der, gegeben einen DAG \(G=(V,E)\) und einen Knoten \(u \in V\) einen längsten mit \(u\) beginnenden Pfad findet. Ihr Algorithmus sollte effizient sein, idealerweise also Laufzeit \(O(n+m)\) haben.
Übungsaufgabe Erklären Sie, warum Ihr Algorithmus auf zyklischen Graphen nicht funktioniert.
Übungsaufgabe Beschreiben Sie einen Algorithmus, der, gegeben einen DAG \(G=(V,E)\), einen längsten Pfad in \(G\) findet.
Hinweis: rufen Sie nicht einfach den Algorithmus der vorherigen Übungsaufgabe für jeden Knoten auf. Dies würde zu einer Laufzeit \(O(n(n+m))\) führen. Beschreiben Sie einen Algorithmus mit Laufzeit \(O(n+m)\).
Übungsaufgabe
Implementieren Sie Ihre zwei vorherigen Algorithmen als
Java-Programm! Im speziellen: schreiben Sie ein Programm
FindLongestPath.java
, das die englische
Vokabelliste einliest und dann vom User ein Wort
einliest und den längsten mit diesem Wort
beginnenden Pfad ausgibt, also beim Input
whines
beispielsweise
whines, whine, wine, win, in, I
Übungsaufgabe
Modifizieren Sie Ihr Programm so, dass es nun
statt Wörtern vom User auch Zahlen einliest.
Bei Eingabe einer Zahl \(k\) soll es die Menge
aller Wörter ausgeben, die den Anfang eines Pfades
der Länge 5 bilden. Bei Eingabe von 6 soll also unter Anderem
das Wort whines
ausgegeben werden.