Dies ist eine alte Version des Dokuments!
(A1)
Untersuche im Graphentester den Algorithmus "MST (Prim)" zur Bestimmung des minimalen Spannbaums mit der Insel-Karte (04_inseln.csv
im Ordner 08_minimalspanningtree
).
Beschreibung des Algorithmus von Prim
Dieser Algorithmus startet mit einem beliebigen Knoten. Dieser wird markiert. Sukzessive werden an diesen Knoten weitere Knoten angebunden und so allmählich ein immer größerer Baum aufgebaut. Dabei wird derjenige Knoten dem Baum hinzugefügt, zu dem die kürzeste Kante vom bisherigen Baum führt. Diese Kante wird markiert.
Auch hier startet man damit, die Kanten nach ihrem Gewicht zu sortieren. Nun sucht man in dieser Liste nach einer Kante, bei der ein Knoten markiert ist und der andere nicht. Dabei kann man alle Kanten, bei denen beide Knoten markiert sind, streichen, da sie nie mehr gebraucht werden.
Hat man eine derartige Kante gefunden, wird sie markiert und aus der Liste entfernt. Der neu angebundene Knoten wird ebenfalls markiert. Diese Schritte wiederholt man, bis alle Knoten angebunden sind, also n-1 mal bei n Knoten.
1)
Dies ist der Graph, zu dem der Algorithmus von Prim einen minimalen Spannbaum berechnet. Die Zahlen bei den einzelnen Kanten geben das jeweilige Kantengewicht an.
Als Startknoten für den Spannbaum T wird der Knoten D gewählt. (Es könnte auch jeder andere Knoten ausgewählt werden.)
Mit dem Startknoten können die Knoten A,B,E und F jeweils unmittelbar durch die Kanten DA, DB, DE und DF verbunden werden.
Unter diesen Kanten ist DA diejenige mit dem geringsten Gewicht und wird deshalb zusammen mit dem Knoten A zum Graphen T hinzugefügt.
Mit dem bestehenden Graphen T kann der Knoten B durch die Kanten AB oder DB, der Knoten E durch die Kante DE und der Knoten F durch die Kante DF verbunden werden. Unter diesen vier Kanten ist DF diejenige mit dem geringsten Gewicht und wird deshalb zusammen mit dem Knoten F zum Graphen T hinzugefügt.
Mit dem bestehenden Graphen T kann der Knoten B durch die Kanten AB oder DB, der Knoten E durch die Kanten DE oder FE und der Knoten G durch die Kante FG verbunden werden. Unter diesen Kanten ist AB diejenige mit dem geringsten Gewicht und wird deshalb zusammen mit dem Knoten B zum Graphen T hinzugefügt.
Mit dem bestehenden Graphen T kann der Knoten C durch die Kante BC, der Knoten E durch die Kanten BE, DE oder FE und der Knoten G durch die Kante FG verbunden werden. Unter diesen Kanten ist BE diejenige mit dem geringsten Gewicht und wird deshalb zusammen mit dem Knoten E zum Graphen T hinzugefügt.
Mit dem bestehenden Graphen T kann der Knoten C durch die Kanten BC oder EC und der Knoten G durch die Kanten EG oder FG verbunden werden. Unter diesen Kanten ist EC diejenige mit dem geringsten Gewicht und wird deshalb zusammen mit dem Knoten C zum Graphen T hinzugefügt.
Der verbliebene Knoten G kann durch die Kanten EG oder FG mit dem Graphen T verbunden werden. Da EG unter diesen beiden das geringere Gewicht hat, wird sie zusammen mit dem Knoten G zum Graphen T hinzugefügt
Der Graph T enthält jetzt alle Knoten des Ausgangsgraphen und ist ein minimaler Spannbaum dieses Ausgangsgraphen.
(A2)
Übersetze die Beschreibung aus Aufgabe 1 in Pseudocode.
Pseudocode Kruskal
Minimal spanning tree:
Setze farbnummer auf 1
Hole eine Liste aller Kanten und sortiere sie aufsteigend
Wiederhole für jede Kante
k1 = Startknoten, k2 = Zielknoten der Kante
Falls Farbe von k1==0 und Farbe von k2==0
Setze Farbe beider Knoten auf farbnummer
Markiere die Kante
Erhöhe die Farbnummer um 1
Sonst
Falls Farbe eines Knotens==0
Setze Farbe dieses Knotens auf die des anderen
Markiere die Kante
Sonst
Falls beide Knoten unterschiedliche Farben haben
Wiederhole für jeden Knoten k im Graph
Falls Farbe von k die Farbe von k2 hat
Setze Farbe von k auf die Farbe von k1
Ende-Falls
Ende-Wiederhole
Markiere die Kante
Sonst
Lösche Kante
Ende-Falls
Ende-Falls
(A3)
Implementiere eine eigene Version des Kruskal-Algorithmus im Graphentester.
Lösungsvorschlag
int farbe = 1;
List<Kante> kanten = g.getAlleKanten();
List<Knoten> knoten = g.getAlleKnoten();
Collections.sort(kanten);
for (Kante k: kanten) {
int f1 = k.getStart().getFarbe();
int f2 = k.getZiel().getFarbe();
if(f1 == 0 && f2 == 0) {
k.getStart().setFarbe(farbe);
k.getZiel().setFarbe(farbe);
k.setMarkiert(true);
farbe++;
} else
if(f1 == 0) {
k.getStart().setFarbe(f2);
k.setMarkiert(true);
} else
if(f2 == 0) {
k.getZiel().setFarbe(f1);
k.setMarkiert(true);
} else
if(f1 == f2) {
k.setGeloescht(true);
} else
{
for(Knoten k1 : knoten) {
if(k1.getFarbe() == f2) k1.setFarbe(f1);
}
k.setMarkiert(true);
}
}