Kürzeste Wege mit dem Algorithmus von Dijkstra
Ein Navigationsgerät sucht nicht den Weg mit den wenigsten Abbiegungen, sondern den mit der kürzesten Fahrzeit. Die Breitensuche aus der letzten Lektion zählt aber nur Kanten und behandelt jede Straße gleich. Sobald die Kanten Gewichte tragen (Länge in Kilometern, Fahrzeit, Kosten), brauchen wir ein Verfahren, das Gewichte aufsummiert.
Der Niederländer Edsger Dijkstra hat 1956 ein Verfahren gefunden, das dieses Problem effizient löst. Seine Grundidee ist einfach: Der Knoten, der von allen noch nicht fertig behandelten Knoten am nächsten am Start liegt, kann sich nicht mehr verbessern, denn jeder andere Weg zu ihm müsste über einen Knoten laufen, der mindestens ebenso weit weg ist. Das Verfahren fixiert also immer den nächsten Knoten, und der Abstand der übrigen wird laufend verbessert. Im Werkzeug Graphalgorithmen kannst du das Verfahren auf eigenen Graphen schrittweise nachvollziehen.
Gewichteter Graph und kürzester Weg
Ein gewichteter Graph ordnet jeder Kante ein Gewicht zu. Das Gewicht eines Weges ist die Summe der Gewichte seiner Kanten. Ein kürzester Weg von nach ist ein Weg mit kleinstem Gesamtgewicht, und dieses Gewicht heißt der Abstand .
Der kürzeste Weg nach Gewicht ist nicht immer der mit den wenigsten Kanten: Eine Umleitung über viele kurze Straßen kann schneller sein als eine einzige lange.
Algorithmus von Dijkstra
Für jeden Knoten führst du einen vorläufigen Abstand und kennzeichnest Knoten als fertig oder offen. Am Anfang gilt und für alle anderen Knoten .
1. Wähle unter den offenen Knoten den mit dem kleinsten vorläufigen Abstand, nenne ihn , und markiere ihn als fertig. Sein Abstand ist jetzt endgültig.
2. Entspanne alle Kanten zu offenen Nachbarn: Wenn der Weg über kürzer ist als der bisher bekannte, setze den Abstand neu.
3. Wiederhole, bis alle Knoten fertig sind (oder der gesuchte Zielknoten fertig ist).
Voraussetzung: Alle Gewichte müssen nichtnegativ sein. Bei negativen Kantengewichten ist der Beweis nicht mehr gültig, und das Verfahren kann falsche Ergebnisse liefern. Mit einer Prioritätswarteschlange (Heap) beträgt die Laufzeit .
Dijkstra von aus
Dijkstra von aus
Gegeben sind die Knoten und die ungerichteten Kanten mit Gewichten: : , : , : , : , : , : .
Start: , alle anderen .
Schritt 1: ist fertig (Abstand ). Entspannen: , .
Schritt 2: Kleinster offener Abstand ist , also fertig. Entspannen: über kostet , setze . über kostet , setze .
Schritt 3: Kleinster offener Abstand ist , also fertig. Entspannen: über kostet , setze .
Schritt 4: fertig. Entspannen: . Schritt 5: fertig.
Der kürzeste Weg nach ist mit Gesamtgewicht . Er hat vier Kanten; der Weg hätte nur drei Kanten, aber das Gewicht . Gerade solche Fälle löst die Breitensuche falsch.
Zusammenfassung
In einem gewichteten Graphen ist der kürzeste Weg der mit dem kleinsten Gesamtgewicht, nicht der mit den wenigsten Kanten.
Dijkstra fixiert immer den offenen Knoten mit dem kleinsten vorläufigen Abstand und entspannt dessen ausgehende Kanten.
Voraussetzung: alle Kantengewichte sind nichtnegativ.
Mit einer Prioritätswarteschlange ist die Laufzeit .
Mit gespeicherten Vorgängern lässt sich der Weg selbst rekonstruieren.
Übungen
Wie groß ist im Beispielgraphen der kürzeste Abstand von nach ?
Warum darf der Algorithmus von Dijkstra keine negativen Kantengewichte enthalten?
Ein ungerichteter Graph hat die Kanten : , : , : , : , : . Bestimme den kürzesten Abstand von nach .
Erkläre, warum die Breitensuche für gewichtete Graphen nicht den kürzesten Weg nach Gewicht liefert, und gib ein Beispiel an.