Interaktives Graphentheorie-Lernen
Interaktives Graphentheorie-Lernen
Guest User
Using app without sign in
Interaktiver Kürzester-Pfad-Rechner
Findet kürzeste Pfade von der Quelle zu allen Knoten in gewichteten Graphen
Wählen Sie einen Algorithmus und generieren Sie Schritte, um die Visualisierung zu beginnen
Der Dijkstra-Algorithmus berechnet die kürzesten Wege von einem Startknoten zu allen anderen Knoten in einem gewichteten Graphen mit nichtnegativen Kantengewichten. 1959 von Edsger Dijkstra veröffentlicht, ist er der Standardalgorithmus für kürzeste Wege von einer Quelle und die Basis der meisten praktischen Routingsysteme.
Der Algorithmus führt für jeden Knoten eine vorläufige Distanz, anfangs unendlich außer der Quelle bei null. Mit einer Prioritätswarteschlange entnimmt er wiederholt den noch offenen Knoten mit der kleinsten vorläufigen Distanz, erklärt ihn für endgültig und relaxiert jede ausgehende Kante: Ist der Weg über den aktuellen Knoten kürzer als die gespeicherte Distanz des Nachbarn, wird sie aktualisiert. Mit einem Binärheap läuft dies in O((V + E) log V). Nichtnegative Gewichte sind entscheidend; eine negative Kante kann bereits abgeschlossene Knoten ungültig machen.
Der Dijkstra-Algorithmus steuert GPS-Navigation, Internet-Routingprotokolle wie OSPF, Flug- und Nahverkehrsplaner sowie Netzwerklatenz-Analysen. Er erscheint auch in Spielen zur Wegfindung, wenn keine Heuristik verfügbar ist. In Interviews ist er die klassische Antwort auf Fragen zu gewichteten kürzesten Wegen und der Ausgangspunkt für A* und Bellman-Ford.
Dijkstra ist ein gieriger Algorithmus, dessen Korrektheit auf einer einzigen Behauptung ruht: Der nächstgelegene noch offene Knoten kann später nicht mehr verbessert werden. Eine Prioritätswarteschlange liefert diesen Knoten in O(log V).
Dijkstra(graph, quelle):
für jeden Knoten v: dist[v] = unendlich
dist[quelle] = 0
pq = Prioritätswarteschlange mit (0, quelle)
solange pq nicht leer ist:
(d, u) = pq.entnimmMinimum()
wenn d > dist[u]: weiter // veralteter Eintrag
für jede Kante (u, v, w):
wenn dist[u] + w < dist[v]:
dist[v] = dist[u] + w
vorgänger[v] = u
pq.einfügen((dist[v], v))Die Prüfung auf veraltete Einträge ist wichtig. Statt den Schlüssel im Heap zu verringern, was die meisten Standardbibliotheken nicht unterstützen, fügt man üblicherweise einen doppelten Eintrag ein und ignoriert jeden, dessen gespeicherte Distanz nicht mehr passt. Das heißt verzögertes Löschen und ist der Grund, warum die Warteschlange bis zu E statt V Einträge halten kann.
Führe Dijkstra von A aus auf einem gewichteten Graphen, in dem sich die gierige Wahl auszahlt, und beobachte, wie die Menge der endgültigen Knoten wächst.
Beispielgraph: Ungerichtete Kanten A-B (4), A-C (2), C-B (1), B-D (5) und C-D (8).
Die Enddistanzen sind A 0, C 2, B 3, D 8, und der kürzeste Weg zu D führt über A, C, B und D. Beachte, dass die direkte Kante A-B mit Gewicht 4 nie genutzt wird: der Weg über C kostet 3. Beachte außerdem, dass die Knoten in der Distanzreihenfolge 0, 2, 3, 8 endgültig werden, was genau die Eigenschaft ist, auf der das gierige Argument beruht.
Zeit: O((V + E) log V) · Speicher: O(V)
Mit einem Binärheap wird jeder der V Knoten einmal zu O(log V) entnommen, und jede der E Kanten kann eine Einfügung zu O(log V) auslösen, was O((V + E) log V) ergibt. Mit verzögertem Löschen enthält der Heap bis zu E Einträge, die Entnahme kostet also O(log E), doch da E höchstens V hoch 2 ist, liegt log E bei höchstens 2 log V und die Schranke bleibt gleich. Ein Fibonacci-Heap verbessert die theoretische Schranke auf O(E + V log V), weil das Verringern des Schlüssels amortisiert O(1) wird, allerdings sind die Konstanten so ungünstig, dass Binärheaps in der Praxis meist gewinnen. Bei einem dichten Graphen liefert ein einfacher Feldsuchlauf nach dem Minimum O(V hoch 2), was den Heap schlägt, sobald E sich V hoch 2 nähert.
Dijkstra ist die Voreinstellung für gewichtete kürzeste Wege. Was ihn ersetzt, hängt davon ab, welche seiner Annahmen dein Graph verletzt.
| Alternative | Vorzuziehen, wenn | Kosten |
|---|---|---|
| BFS | Alle Kanten haben dasselbe Gewicht, die Schrittzahl ist also die Distanz. Strikt schneller. | O(V + E) |
| Bellman-Ford | Ein Kantengewicht ist negativ, was das gierige Festlegungsargument bricht. | O(VE) |
| A*-Suche | Du willst ein bestimmtes Ziel und hast eine zulässige Heuristik, etwa die Luftlinie auf einer Karte. | O((V + E) log V) im schlechtesten Fall |
| Floyd-Warshall | Du brauchst alle paarweisen Distanzen und der Graph ist klein oder dicht. | O(V^3) |
| Bidirektionaler Dijkstra | Eine Quelle, ein Ziel, ein großer Graph und Kanten, die sich rückwärts durchlaufen lassen. | etwa halb so viele erkundete Knoten |
Den ganzen Artikel lesen: Shortest Path Algorithms Explained
Verwandte Algorithmen: Bellman-Ford-Algorithmus, Floyd-Warshall-Algorithmus, Breitensuche