Algoritma Dijkstra ialah algoritma pencarian laluan klasik yang digunakan dalam teori graf untuk mencari laluan terpendek dari nod sumber ke semua nod lain dalam graf. Dalam artikel ini, kami akan meneroka algoritma, bukti ketepatannya dan menyediakan pelaksanaan dalam JavaScript.
Algoritma Dijkstra ialah algoritma tamak yang direka untuk mencari laluan terpendek daripada satu nod sumber dalam graf berwajaran dengan pemberat tepi bukan negatif. Ia telah dicadangkan oleh Edsger W. Dijkstra pada tahun 1956 dan kekal sebagai salah satu algoritma yang paling banyak digunakan dalam sains komputer.
Mulakan jarak:
Gunakan baris gilir keutamaan untuk menyimpan nod berdasarkan jaraknya.
Berulang kali keluarkan nod dengan jarak terkecil dan rilekskan jirannya.
di mana (s) ialah nod sumber, dan (v) mewakili mana-mana nod lain.
Mengapa Ia Berfungsi: Relaksasi memastikan kami sentiasa mencari laluan terpendek ke nod dengan mengemas kini jarak secara berperingkat apabila laluan yang lebih pendek ditemui.
Operasi Beratur:
Kami membuktikan ketepatan algoritma Dijkstra menggunakan aruhan kuat.
Aruhan kuat ialah varian aruhan matematik di mana, untuk membuktikan pernyataan (P(n)) , kami menganggap kebenaran (P(1),P(2),…,P(k)) untuk membuktikan ( P(k 1)) . Ini berbeza daripada induksi biasa, yang menganggap sahaja (P(k)) untuk membuktikan ( P(k 1)) . Terokainya dengan lebih terperinci dalam siaran saya yang lain.
Kes Asas:
Nod sumber
(s)
dimulakan dengan
dist(s)=0
, yang betul.
Hipotesis Induktif:
Andaikan semua nod yang diproses setakat ini mempunyai jarak laluan terpendek yang betul.
Langkah Induktif:
Nod seterusnya
(u)
disingkirkan daripada barisan keutamaan. Sejak
dist(u)
ialah jarak terkecil yang tinggal, dan semua nod sebelumnya mempunyai jarak yang betul,
dist(u)
juga betul.
Prasyarat (Baris Gilir Keutamaan):
// 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; } }
Berikut ialah pelaksanaan JavaScript bagi algoritma Dijkstra menggunakan baris gilir keutamaan:
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);
Bina Semula Laluan
// 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; } }
Mulakan jarak:
Proses A:
Proses B:
Proses C:
Proses D:
Membandingkan kerumitan masa algoritma Dijkstra dengan pelaksanaan baris gilir keutamaan yang berbeza:
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) |
Algoritma Dijkstra ialah kaedah yang berkuasa dan cekap untuk mencari laluan terpendek dalam graf dengan pemberat bukan negatif. Walaupun ia mempunyai had (cth., tidak boleh mengendalikan pemberat tepi negatif), ia digunakan secara meluas dalam rangkaian, penghalaan dan aplikasi lain.
Berikut ialah beberapa sumber terperinci di mana anda boleh meneroka algoritma Dijkstra bersama-sama dengan bukti dan contoh yang ketat:
Selain itu, Wikipedia menawarkan gambaran keseluruhan topik yang hebat.
Petikan:
[1] https://www.fuhuthu.com/CPSC420F2019/dijkstra.pdf
Jangan ragu untuk berkongsi pendapat atau penambahbaikan anda dalam ulasan!
Atas ialah kandungan terperinci Memahami Algoritma Dijkstra: Dari Teori kepada Perlaksanaan. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!