Der Dijkstra-Algorithmus ist ein klassischer Pfadfindungsalgorithmus, der in der Graphentheorie verwendet wird, um den kürzesten Pfad von einem Quellknoten zu allen anderen Knoten in einem Diagramm zu finden. In diesem Artikel untersuchen wir den Algorithmus, seinen Korrektheitsnachweis und stellen eine Implementierung in JavaScript bereit.
Dijkstras Algorithmus ist ein Greedy-Algorithmus, der darauf ausgelegt ist, die kürzesten Pfade von einem einzelnen Quellknoten in einem gewichteten Diagramm mit nicht negativen Kantengewichten zu finden. Er wurde 1956 von Edsger W. Dijkstra vorgeschlagen und ist nach wie vor einer der am weitesten verbreiteten Algorithmen in der Informatik.
Distanzen initialisieren:
Verwenden Sie eine Prioritätswarteschlange, um Knoten basierend auf ihrer Entfernung zu speichern.
Entfernen Sie wiederholt den Knoten mit dem kleinsten Abstand und entspannen Sie seine Nachbarn.
wo (s) ist der Quellknoten und (v) repräsentiert jeden anderen Knoten.
Warum es funktioniert: Durch die Entspannung wird sichergestellt, dass wir immer den kürzesten Weg zu einem Knoten finden, indem die Entfernung schrittweise aktualisiert wird, wenn ein kürzerer Weg gefunden wird.
Warteschlangenbetrieb:
Wir beweisen die Korrektheit des Dijkstra-Algorithmus mithilfe von starker Induktion.
Starke Induktion ist eine Variante der mathematischen Induktion, bei der es darum geht, eine Aussage zu beweisen (P(n)) , wir gehen von der Wahrheit aus (P(1),P(2),…,P(k)) zu beweisen ( P(k 1)) . Dies unterscheidet sich von der regulären Induktion, bei der nur angenommen wird (P(k)) zu beweisen ( P(k 1)) . Erfahren Sie mehr darüber in meinem anderen Beitrag.
Basisfall:
Der Quellknoten
(s)
wird mit initialisiert
dist(s)=0
, was richtig ist.
Induktive Hypothese:
Gehen Sie davon aus, dass alle bisher verarbeiteten Knoten die richtigen kürzesten Pfadabstände haben.
Induktiver Schritt:
Der nächste Knoten
(u)
wird aus der Prioritätswarteschlange entfernt. Seit
dist(u)
ist der kleinste verbleibende Abstand und alle vorherigen Knoten haben korrekte Abstände,
dist(u)
ist auch richtig.
Voraussetzungen (Prioritätswarteschlange):
// Simplified Queue using Sorting // Use Binary Heap (good) // or Binomial Heap (better) or Pairing Heap (best) class PriorityQueue { constructor() { this.queue = []; } enqueue(node, priority) { this.queue.push({ node, priority }); this.queue.sort((a, b) => a.priority - b.priority); } dequeue() { return this.queue.shift(); } isEmpty() { return this.queue.length === 0; } }
Hier ist eine JavaScript-Implementierung des Dijkstra-Algorithmus unter Verwendung einer Prioritätswarteschlange:
function dijkstra(graph, start) { const distances = {}; // hold the shortest distance from the start node to all other nodes const previous = {}; // Stores the previous node for each node in the shortest path (used to reconstruct the path later). const pq = new PriorityQueue(); // Used to efficiently retrieve the node with the smallest tentative distance. // Initialize distances and previous for (let node in graph) { distances[node] = Infinity; // Start with infinite distances previous[node] = null; // No previous nodes at the start } distances[start] = 0; // Distance to the start node is 0 pq.enqueue(start, 0); while (!pq.isEmpty()) { const { node } = pq.dequeue(); // Get the node with the smallest tentative distance for (let neighbor in graph[node]) { const distance = graph[node][neighbor]; // The edge weight const newDist = distances[node] + distance; // Relaxation Step if (newDist < distances[neighbor]) { distances[neighbor] = newDist; // Update the shortest distance to the neighbor previous[neighbor] = node; // Update the previous node pq.enqueue(neighbor, newDist); // Enqueue the neighbor with the updated distance } } } return { distances, previous }; } // Example usage const graph = { A: { B: 1, C: 4 }, B: { A: 1, C: 2, D: 5 }, C: { A: 4, B: 2, D: 1 }, D: { B: 5, C: 1 } }; const result = dijkstra(graph, 'A'); // start node 'A' console.log(result);
Pfad rekonstruieren
// Simplified Queue using Sorting // Use Binary Heap (good) // or Binomial Heap (better) or Pairing Heap (best) class PriorityQueue { constructor() { this.queue = []; } enqueue(node, priority) { this.queue.push({ node, priority }); this.queue.sort((a, b) => a.priority - b.priority); } dequeue() { return this.queue.shift(); } isEmpty() { return this.queue.length === 0; } }
Distanzen initialisieren:
Prozess A:
Prozess B:
Prozess C:
Prozess D:
Vergleich der zeitlichen Komplexität des Dijkstra-Algorithmus mit verschiedenen Implementierungen von Prioritätswarteschlangen:
Priority Queue Type | Insert (M) | Extract Min | Decrease Key | Overall Time Complexity |
---|---|---|---|---|
Simple Array | O(1) | O(V) | O(V) | O(V^2) |
Binary Heap | O(log V) | O(log V) | O(log V) | O((V E) log V) |
Binomial Heap | O(log V) | O(log V) | O(log V) | O((V E) log V) |
Fibonacci Heap | O(1) | O(log V) | O(1) | O(V log V E) |
Pairing Heap | O(1) | O(log V) | O(log V) | O(V log V E) (practical) |
Der Dijkstra-Algorithmus ist eine leistungsstarke und effiziente Methode zum Finden kürzester Pfade in Diagrammen mit nicht negativen Gewichten. Obwohl es Einschränkungen gibt (z. B. kann es keine negativen Kantengewichte verarbeiten), wird es häufig in Netzwerken, Routing und anderen Anwendungen verwendet.
Hier finden Sie einige detaillierte Ressourcen, in denen Sie den Dijkstra-Algorithmus zusammen mit strengen Beweisen und Beispielen erkunden können:
Außerdem bietet Wikipedia einen tollen Überblick zum Thema.
Zitate:
[1] https://www.fuhuthu.com/CPSC420F2019/dijkstra.pdf
Teilen Sie Ihre Gedanken oder Verbesserungen gerne in den Kommentaren mit!
Das obige ist der detaillierte Inhalt vonDen Dijkstra-Algorithmus verstehen: Von der Theorie zur Umsetzung. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!