Šiame straipsnyje aptarsime vieną iš dažniausiai žinomų trumpiausio kelio algoritmų, ty Dijkstra's Shortest Path Algorithm, kurį 1956 m. sukūrė olandų kompiuterių mokslininkas Edsgeris W. Dijkstra. Be to, atliksime šio algoritmo sudėtingumo analizę. pažiūrėkite, kuo jis skiriasi nuo kitų trumpiausio kelio algoritmų.
Turinys
- Dijkstros algoritmas
- Dijkstros algoritmo poreikis (tikslas ir naudojimo atvejai)
- Ar Dijkstros algoritmas gali veikti ir nukreiptuose, ir nerežisuotuose grafikuose?
- Dijkstros algoritmo algoritmas
- Kaip veikia Dijkstros algoritmas?
- Dijkstros algoritmo pseudo kodas
- Dijkstros algoritmo įgyvendinimas:
- Dijkstra algoritmai vs Bellman-Ford algoritmas
- Dijkstros algoritmas prieš Floydo-Warshall algoritmą
- Dijkstros algoritmas prieš A* algoritmą
- Praktikuokite Dijkstros algoritmo problemas
- Išvada:

Dijkstros algoritmas:
Dijkstros algoritmas yra populiarus algoritmas, sprendžiantis daugelį vieno šaltinio trumpiausio kelio uždavinių, turinčių neneigiamą kraštų svorį grafuose, ty rasti trumpiausią atstumą tarp dviejų grafo viršūnių. Jį sugalvojo olandų kompiuterių mokslininkas Edsgeris W. Dijkstra 1956 metais.
Algoritmas palaiko aplankytų viršūnių rinkinį ir neaplankytų viršūnių rinkinį. Jis prasideda nuo šaltinio viršūnės ir iteratyviai pasirenka nelankytą viršūnę su mažiausiu preliminariu atstumu nuo šaltinio. Tada jis aplanko šios viršūnės kaimynus ir atnaujina jų preliminarius atstumus, jei randamas trumpesnis kelias. Šis procesas tęsiasi tol, kol pasiekiama paskirties viršūnė arba aplankomos visos pasiekiamos viršūnės.
Dijkstros algoritmo poreikis (tikslas ir naudojimo atvejai)
Dijkstra algoritmo poreikis kyla daugelyje programų, kuriose labai svarbu rasti trumpiausią kelią tarp dviejų taškų.
Pavyzdžiui , Jis gali būti naudojamas kompiuterių tinklų maršruto parinkimo protokoluose, taip pat naudojamas žemėlapių sistemose, norint rasti trumpiausią kelią tarp pradžios taško ir paskirties vietos (kaip paaiškinta Kaip veikia „Google“ žemėlapiai? )
Ar Dijkstros algoritmas gali veikti ir nukreiptuose, ir nerežisuotuose grafikuose?
Taip , Dijkstra algoritmas gali veikti tiek nukreiptuose, tiek neorientuotuose grafikuose, nes šis algoritmas sukurtas dirbti su bet kokio tipo grafiku, jei jis atitinka neneigiamų briaunų svorių ir prijungimo reikalavimus.
- Nukreiptame grafike kiekviena briauna turi kryptį, nurodant judėjimo kryptį tarp briauna sujungtų viršūnių. Šiuo atveju, ieškodamas trumpiausio kelio, algoritmas vadovaujasi kraštų kryptimi.
- Nenukreiptame grafike briaunos neturi krypties, o ieškant trumpiausio kelio algoritmas gali važiuoti tiek pirmyn, tiek atgal išilgai kraštų.
Dijkstros algoritmo algoritmas:
- Pažymėkite šaltinio mazgą srovės atstumu 0, o likusius - begalybe.
- Nustatykite neaplankytą mazgą su mažiausiu dabartiniu atstumu kaip dabartinį mazgą.
- Kiekvienam kaimynui dabartinio mazgo N prideda esamą gretimo mazgo atstumą su krašto, jungiančio 0->1, svoriu. Jei jis mažesnis už dabartinį mazgo atstumą, nustatykite jį kaip naują dabartinį N atstumą.
- Pažymėkite dabartinį 1 mazgą kaip aplankytą.
- Jei yra neaplankytų mazgų, pereikite prie 2 veiksmo.
Kaip veikia Dijkstros algoritmas?
Pažiūrėkime, kaip veikia Dijkstra algoritmas su toliau pateiktu pavyzdžiu:
Dijkstra algoritmas sukurs trumpiausią kelią nuo 0 mazgo iki visų kitų grafiko mazgų.
Apsvarstykite žemiau pateiktą grafiką:
Dijkstros algoritmas
Algoritmas generuos trumpiausią kelią nuo 0 mazgo iki visų kitų grafiko mazgų.
Šiame grafike darysime prielaidą, kad kraštų svoris reiškia atstumą tarp dviejų mazgų.
java skaitiklisKaip matome, turime trumpiausią kelią nuo
0 mazgas 1 mazgas, nuo
0 mazgas 2 mazgas, nuo
Mazgas 0 iki 3 mazgas, nuo
Mazgas 0 iki 4 mazgas, nuo
Nuo 0 iki 6 mazgo.Iš pradžių turime toliau pateiktą išteklių rinkinį:
- Atstumas nuo šaltinio mazgo iki jo paties yra 0. Šiame pavyzdyje šaltinio mazgas yra 0.
- Atstumas nuo šaltinio mazgo iki visų kitų mazgų nežinomas, todėl juos visus pažymime kaip begalybę.
Pavyzdys: 0 -> 0, 1-> ∞,2-> ∞,3-> ∞,4-> ∞,5-> ∞,6-> ∞.
- taip pat turėsime daugybę nelankytų elementų, kurie stebės nelankytus arba nepažymėtus mazgus.
- Algoritmas bus baigtas, kai visi mazgai pažymėti kaip aplankyti ir atstumas tarp jų bus pridėtas prie kelio. Nelankyti mazgai:- 0 1 2 3 4 5 6.
1 žingsnis: Pradėkite nuo 0 mazgo ir pažymėkite Mazgą kaip aplankytą, nes galite užsiregistruoti žemiau esančiame aplankytame paveikslėlyje Mazgas pažymėtas raudonai.
Dijkstros algoritmas
2 žingsnis: Patikrinkite, ar nėra gretimų mazgų. Dabar turime pasirinkti (arba pasirinkti 1 mazgą, kurio atstumas yra 2, arba 2 mazgą su atstumu 6 ) ir pasirinkti Mazgą su mažiausiu atstumu. Šiame žingsnyje 1 mazgas yra Minimalus atstumas šalia mazgo, todėl pažymėjo jį kaip aplankytą ir pridėkite atstumą.
Atstumas: 0 mazgas -> 1 mazgas = 2
Dijkstros algoritmas
3 veiksmas: Tada pereikite į priekį ir patikrinkite, ar nėra gretimo mazgo, kuris yra 3 mazgas, todėl pažymėjote jį kaip aplankytą ir pridėkite atstumą. Dabar atstumas bus toks:
Atstumas: 0 mazgas -> 1 mazgas -> 3 mazgas = 2 + 5 = 7
ins raktasDijkstros algoritmas
4 veiksmas: Vėlgi, turime du gretimų mazgų pasirinkimus (galime pasirinkti 4 mazgą, kurio atstumas yra 10, arba 5 mazgą, kurio atstumas yra 15), todėl pasirinkite Mazgą su minimaliu atstumu. Šiame žingsnyje 4 mazgas yra Minimalus atstumas šalia mazgo, todėl pažymėjo jį kaip aplankytą ir pridėkite atstumą.
Atstumas: 0 mazgas -> 1 mazgas -> 3 mazgas -> 4 mazgas = 2 + 5 + 10 = 17
Dijkstros algoritmas
5 veiksmas: Vėlgi, pereikite į priekį ir patikrinkite, ar nėra gretimo mazgo, kuris yra 6 mazgas , todėl pažymėjote kaip aplankytą ir pridėkite atstumą, Dabar atstumas bus:
Atstumas: 0 mazgas -> 1 mazgas -> 3 mazgas -> 4 mazgas -> 6 mazgas = 2 + 5 + 10 + 2 = 19
Dijkstros algoritmas
už loop bashTaigi, trumpiausias atstumas nuo šaltinio viršūnės yra 19, kuris yra optimalus
Dijkstros algoritmo pseudo kodas
funkcija Dijkstra (grafikas, šaltinis):
// Atstumus iki visų mazgų inicijuokite kaip begalybę, o iki šaltinio mazgo – kaip 0.atstumai = žemėlapis (visi mazgai -> begalybė)
atstumai = 0
// Inicijuokite tuščią aplankytų mazgų rinkinį ir prioritetinę eilę, kad galėtumėte sekti aplankomus mazgus.
aplankyta = tuščias rinkinys
eilė = nauja PriorityQueue()
queue.enqueue(šaltinis, 0)// Ciklas, kol bus aplankyti visi mazgai.
kol eilė nėra tuščia:
// Ištraukite į eilę mazgo, kurio atstumas yra mažiausias nuo prioritetinės eilės.
srovė = eilė.dequeue()// Jei mazgas jau buvo aplankytas, praleiskite jį.
jei dabar lankėtės:
Tęsti// Pažymėkite mazgą kaip aplankytą.
visited.add(current)// Patikrinkite visus gretimus mazgus, kad pamatytumėte, ar jų atstumus reikia atnaujinti.
kaimynui Graph.neighbors(dabartinis):
// Apskaičiuokite preliminarų atstumą iki kaimyno per dabartinį mazgą.
preliminarus_atstumas = atstumai[dabartinis] + grafikas.atstumas(dabartinis, kaimynas)// Jei preliminarus atstumas yra mažesnis nei dabartinis atstumas iki kaimyno, atnaujinkite atstumą.
jei preliminarus_atstumas
atstumai[kaimynas] = preliminarus_atstumas// Įkelkite kaimyną į eilę su nauju atstumu, kad jį būtų galima aplankyti ateityje.
eilė.eilė(kaimynas, atstumai[kaimynas])// Grąžinti apskaičiuotus atstumus nuo šaltinio iki visų kitų grafiko mazgų.
grįžimo atstumai
Dijkstros algoritmo įgyvendinimas:
Yra keli Dijkstra algoritmo įgyvendinimo būdai, tačiau dažniausiai naudojami šie:
- Prioritetinė eilė (diegimas pagal krūvą):
- Masyvu pagrįstas diegimas:
1. Dijkstra trumpiausio kelio algoritmas naudojant priority_queue (heap)
Šiame įgyvendinime mums pateikiamas grafikas ir grafo šaltinio viršūnė, surandant trumpiausius kelius nuo šaltinio iki visų duoto grafo viršūnių.
Pavyzdys:
Įvestis: Šaltinis = 0
Pavyzdys
Išvestis: Viršūnė
Viršūnių atstumas nuo šaltinio
0 -> 0
1 -> 2
2 -> 6
3 -> 7
4 -> 17
5 -> 22
6 -> 19
Žemiau pateikiamas algoritmas, pagrįstas aukščiau pateikta idėja:
- Inicijuoti atstumo reikšmes ir prioriteto eilę.
- Įdėkite šaltinio mazgą į prioritetinę eilę su 0 atstumu.
- Nors prioritetinė eilė nėra tuščia:
- Išskleiskite mazgą, esantį mažiausiu atstumu nuo prioritetinės eilės.
- Atnaujinkite kaimynų atstumus, jei randamas trumpesnis kelias.
- Į prioritetinę eilę įterpkite atnaujintus kaimynus.
Žemiau pateikiamas aukščiau pateikto metodo C++ įgyvendinimas:
C++ // Program to find Dijkstra's shortest path using // priority_queue in STL #include using namespace std; #define INF 0x3f3f3f3f // iPair ==>Integer Pair typedef pora iPair; // Ši klasė vaizduoja nukreiptą grafiką naudojant // gretimų sąrašo reprezentacijos klasė Graph { int V; // Viršūnių skaičius // Svertiniame grafe turime išsaugoti kiekvieno briaunų sąrašo viršūnę // ir svorio porą>> adj; vieša: Grafas(int V); // Konstruktorius // funkcija pridėti briauną į grafiką void addEdge(int u, int v, int w); // spausdina trumpiausią kelią iš s void shortestPath(int s); }; // Skiria atmintį gretimų sąrašui Graph::Graph(int V) { this->V = V; adj = naujas sąrašas [V]; } void Graph::addEdge(int u, int v, int w) { adj[u].push_back(make_pair(v, w)); adj[v].push_back(make_pair(u, w)); } // Spausdina trumpiausius kelius nuo src iki visų kitų viršūnių void Graph::shortestPath(int src) { // Sukurkite prioritetinę eilę viršūnėms, kurios // yra iš anksto apdorojamos, saugoti. Tai keista C++ sintaksė. // Norėdami sužinoti daugiau apie šią sintaksę, žr. toliau pateiktą nuorodą // https://www.techcodeview.com priority_queue , didesnis > pq; // Sukurkite atstumų vektorių ir inicijuokite visus // atstumus kaip begalinį (INF) vektorių dist(V, INF); // Įterpti patį šaltinį į prioritetinę eilę ir inicijuoti // jo atstumą kaip 0. pq.push(make_pair(0, src)); dist[src] = 0; /* Perėjimas, kol prioritetinė eilė tampa tuščia (arba visi atstumai nėra užbaigti) */ while (!pq.empty()) { // Pirmoji poros viršūnė yra mažiausias atstumas // viršūnė, ištraukite ją iš prioritetinės eilės. // viršūnių etiketė saugoma antroje poroje (tai // turi būti padaryta taip, kad viršūnės išliktų // surūšiuotas atstumas (atstumas turi būti pirmasis elementas // poroje) int u = pq.top().second; pq.pop(); // 'i' naudojamas visoms gretimoms // viršūnių sąrašo viršūnėms gauti>::iteratorius i; for (i = adj[u].begin(); i != adj[u].end(); ++i) { // Gauti viršūnės etiketę ir srovės svorį // greta u. int v = (*i).pirma; int svoris = (*i).sekundė; // Jei yra sutrumpintas kelias į v per u. if (dist[v]> dist[u] + svoris) { // Atnaujinamas v atstumas dist[v] = dist[u] + svoris; pq.push(make_pair(dist[v], v)); } } } // Spausdinti trumpiausius atstumus, saugomus dist[] printf('Vertex Distance from Source
'); už (int i = 0; i< V; ++i) printf('%d %d
', i, dist[i]); } // Driver program to test methods of graph class int main() { // create the graph given in above figure int V = 7; Graph g(V); // making above shown graph g.addEdge(0, 1, 2); g.addEdge(0, 2, 6); g.addEdge(1, 3, 5); g.addEdge(2, 3, 8); g.addEdge(3, 4, 10); g.addEdge(3, 5, 15); g.addEdge(4, 6, 2); g.addEdge(5, 6, 6); g.shortestPath(0); return 0; }>
Java import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.PriorityQueue; public class DijkstraAlgoForShortestDistance { static class Node implements Comparable{ int v; int atstumas; viešasis mazgas(int v, int atstumas) { this.v = v; tai.atstumas = atstumas; } @Nepaisyti viešosios int palygintiTo(Node n) { if (this.distance<= n.distance) { return -1; } else { return 1; } } } static int[] dijkstra( int V, ArrayList >> adj, int S) { loginis [] aplankytas = naujas loginis [V]; HashMap žemėlapis = naujas HashMap(); PriorityQueueq = new PriorityQueue(); map.put(S, new Node(S, 0)); q.add(new Node(S, 0)); while (!q.isEmpty()) { Mazgas n = q.poll(); int v = n.v; int atstumas = n.atstumas; aplankytas[v] = tiesa; ArrayList > adjList = adj.get(v); už (ArrayList adjLink : adjList) { if (aplankyta[adjLink.get(0)] == false) { if (!map.containsKey(adjLink.get(0))) { map.put( adjLink.get(0), naujas mazgas (v, atstumas + adjLink.get(1))); } else { Mazgas sn = map.get(adjLink.get(0)); if (atstumas + adjLink.get(1)< sn.distance) { sn.v = v; sn.distance = distance + adjLink.get(1); } } q.add(new Node(adjLink.get(0), distance + adjLink.get(1))); } } } int[] result = new int[V]; for (int i = 0; i < V; i++) { result[i] = map.get(i).distance; } return result; } public static void main(String[] args) { ArrayList >> adj = new ArrayList(); HashMap >> žemėlapis = naujas HashMap(); int V = 6; int E = 5; int[] u = { 0, 0, 1, 2, 4 }; int[] v = { 3, 5, 4, 5, 5 }; int[] w = { 9, 4, 4, 10, 3 }; už (int i = 0; i< E; i++) { ArrayList kraštas = naujas ArrayList(); kraštas.add(v[i]); kraštas.add(w[i]); ArrayList > adjList; if (!map.containsKey(u[i])) { adjList = new ArrayList(); } else { adjList = map.get(u[i]); } adjList.add(edge); map.put(u[i], adjList); ArrayList kraštas2 = naujas ArrayList(); kraštas2.add(u[i]); kraštas2.add(w[i]); ArrayList > adjList2; if (!map.containsKey(v[i])) { adjList2 = new ArrayList(); } else { adjList2 = map.get(v[i]); } adjList2.add(edge2); map.put(v[i], adjList2); } for (int i = 0; i< V; i++) { if (map.containsKey(i)) { adj.add(map.get(i)); } else { adj.add(null); } } int S = 1; // Input sample //[0 [[3, 9], [5, 4]], // 1 [[4, 4]], // 2 [[5, 10]], // 3 [[0, 9]], // 4 [[1, 4], [5, 3]], // 5 [[0, 4], [2, 10], [4, 3]] //] int[] result = DijkstraAlgoForShortestDistance.dijkstra( V, adj, S); System.out.println(Arrays.toString(result)); } }> Python # Python implementation of Dijkstra Algorithm import heapq class Node: def __init__(self, v, distance): self.v = v self.distance = distance def __lt__(self, other): return self.distance < other.distance def dijkstra(V, adj, S): visited = [False] * V map = {} q = [] map[S] = Node(S, 0) heapq.heappush(q, Node(S, 0)) while q: n = heapq.heappop(q) v = n.v distance = n.distance visited[v] = True adjList = adj[v] for adjLink in adjList: if not visited[adjLink[0]]: if adjLink[0] not in map: map[adjLink[0]] = Node(v, distance + adjLink[1]) else: sn = map[adjLink[0]] if distance + adjLink[1] < sn.distance: sn.v = v sn.distance = distance + adjLink[1] heapq.heappush(q, Node(adjLink[0], distance + adjLink[1])) result = [0] * V for i in range(V): result[i] = map[i].distance return result def main(): adj = [[] for _ in range(6)] V = 6 E = 5 u = [0, 0, 1, 2, 4] v = [3, 5, 4, 5, 5] w = [9, 4, 4, 10, 3] for i in range(E): edge = [v[i], w[i]] adj[u[i]].append(edge) edge2 = [u[i], w[i]] adj[v[i]].append(edge2) S = 1 result = dijkstra(V, adj, S) print(result) if __name__ == '__main__': main() # This code is contributed by ragul21> C# // C# Code: using System; using System.Collections.Generic; public class Graph { // No. of vertices private int V; // adjacency list private List>[] adj; // Konstruktorius public Graph(int v) { V = v; adj = naujas sąrašas>[ v ]; už (int i = 0; i< v; ++i) adj[i] = new List>(); } // funkcija pridėti briauną į grafiką public void addEdge(int u, int v, int w) { adj[u].Add(Tuple.Create(v, w)); adj[v].Add(Tuple.Create(u, w)); } // spausdina trumpiausią kelią iš s public void shortestPath(int s) { // Sukurkite prioritetinę eilę, kurioje saugomos viršūnės, kurios // yra iš anksto apdorojamos. var pq = nauja PriorityQueue>(); // Sukurti atstumų vektorių ir inicijuoti visus // atstumus kaip begalinius (INF) var dist = new int[V]; už (int i = 0; i< V; i++) dist[i] = int.MaxValue; // Insert source itself in priority queue and // initialize its distance as 0. pq.Enqueue(Tuple.Create(0, s)); dist[s] = 0; /* Looping till priority queue becomes empty (or all distances are not finalized) */ while (pq.Count != 0) { // The first vertex in pair is the minimum // distance vertex, extract it from priority // queue. vertex label is stored in second of // pair (it has to be done this way to keep the // vertices sorted distance (distance must be // first item in pair) var u = pq.Dequeue().Item2; // 'i' is used to get all adjacent vertices of a // vertex foreach(var i in adj[u]) { // Get vertex label and weight of current // adjacent of u. int v = i.Item1; int weight = i.Item2; // If there is shorted path to v through u. if (dist[v]>dist[u] + svoris) { // Atnaujinamas v atstumas dist[v] = dist[u] + svoris; pq.Enqueue(Tuple.Create(dist[v], v)); } } } // Spausdinti trumpiausius atstumus, saugomus dist[] Console.WriteLine('Vertex Distance from Source'); už (int i = 0; i< V; ++i) Console.WriteLine('{0} {1}', i, dist[i]); } } public class PriorityQueue{ privatus, tik skaitomas sąrašas_duomenys; privatus, tik skaitomas palyginimas_palyginti; public PriorityQueue(): this(Palyginti.Numatytasis) { } public PriorityQueue(IComparerpalyginti): this(palyginti.Palyginti) { } public PriorityQueue(palyginimaspalyginimas) { _duomenys = naujas sąrašas(); _palyginti = palyginimas; } public void Eilė(T elementas) { _duomenys.Pridėti(elementas); var childIndex = _duomenys.Skaičius – 1; while (childIndex> 0) { var parentIndex = (childIndex - 1) / 2; if (_palyginti(_duomenys[vaikoIndeksas], _duomenys[parentIndex])>= 0) pertrauka; T tmp = _duomenys[vaiko indeksas]; _duomenys[vaikoIndeksas] = _duomenys[parentIndex]; _duomenys[parentIndex] = tmp; vaikasIndex = parentIndex; } } public T Dequeue() { // daro prielaidą, kad pq nėra tuščias; iki iškvietimo kodo var lastElement = _duomenys.Skaičius - 1; var frontItem = _duomenys[0]; _duomenys[0] = _duomenys[paskutinis elementas]; _data.RemoveAt(lastElement); --lastElement; var parentIndex = 0; while (true) { var childIndex = parentIndex * 2 + 1; if (childIndex> lastElement) pertrauka; // Medžio pabaiga var rightChild = vaikasIndex + 1; jei (teisingasVaikas<= lastElement && _compare(_data[rightChild], _data[childIndex]) < 0) childIndex = rightChild; if (_compare(_data[parentIndex], _data[childIndex]) <= 0) break; // Correct position T tmp = _data[parentIndex]; _data[parentIndex] = _data[childIndex]; _data[childIndex] = tmp; parentIndex = childIndex; } return frontItem; } public T Peek() { T frontItem = _data[0]; return frontItem; } public int Count { get { return _data.Count; } } } class Program { // Driver program to test methods of graph class static void Main(string[] args) { // create the graph given in above figure int V = 7; Graph g = new Graph(V); // making above shown graph g.addEdge(0, 1, 2); g.addEdge(0, 2, 6); g.addEdge(1, 3, 5); g.addEdge(2, 3, 8); g.addEdge(3, 4, 10); g.addEdge(3, 5, 15); g.addEdge(4, 6, 2); g.addEdge(5, 6, 6); g.shortestPath(0); } }> Javascript class PriorityQueue { constructor() { this.queue = []; } enqueue(element, priority) { this.queue.push({ element, priority }); this.queue.sort((a, b) =>a.priority - b.priority); } dequeue() { if (this.isEmpty()) { return null; } return this.queue.shift().element; } isEmpty() { return this.queue.length === 0; } } class Grafikas { konstruktorius(V) { this.V = V; this.adj = naujas Masyvas(V); for (tegul i = 0; i< V; i++) { this.adj[i] = []; } } addEdge(u, v, w) { this.adj[u].push({ v, w }); this.adj[v].push({ v: u, w }); } shortestPath(src) { const pq = new PriorityQueue(); const dist = new Array(this.V).fill(Infinity); const visited = new Array(this.V).fill(false); pq.enqueue(src, 0); dist[src] = 0; while (!pq.isEmpty()) { const u = pq.dequeue(); if (visited[u]) continue; visited[u] = true; for (const { v, w } of this.adj[u]) { if (!visited[v] && dist[u] + w < dist[v]) { dist[v] = dist[u] + w; pq.enqueue(v, dist[v]); } } } console.log('Vertex Distance from Source'); for (let i = 0; i < this.V; i++) { console.log(`${i} ${dist[i] === Infinity ? 'Infinity' : dist[i]}`); } } } function main() { const V = 7; const g = new Graph(V); g.addEdge(0, 1, 2); g.addEdge(0, 2, 6); g.addEdge(1, 3, 5); g.addEdge(2, 3, 8); g.addEdge(3, 4, 10); g.addEdge(3, 5, 15); g.addEdge(4, 6, 2); g.addEdge(5, 6, 6); g.shortestPath(0); } main();> Galutinis atsakymas:

Išvestis
Dijkstra algoritmo sudėtingumo analizė :
- Laiko sudėtingumas: O((V + E) log V) , kur V yra viršūnių skaičius, o E yra briaunų skaičius.
- Pagalbinė erdvė: O(V), kur V – viršūnių skaičius, o E – kraštinių skaičius grafe.
2.Masyvu pagrįstas Dijkstros algoritmo įgyvendinimas (naivus požiūris):
Dijkstra algoritmas taip pat gali būti įgyvendintas naudojant masyvus, nenaudojant prioritetinės eilės. Šis įgyvendinimas yra nesudėtingas, bet gali būti ne toks efektyvus, ypač dideliuose grafikuose.
Algoritmas vyksta taip:
skaitytuvas java
- Inicijuokite masyvą, kad išsaugotumėte atstumus nuo šaltinio iki kiekvieno mazgo.
- Pažymėkite visus mazgus kaip nelankytus.
- Nustatykite atstumą iki šaltinio mazgo kaip 0 ir begalybę visiems kitiems mazgams.
- Kartokite, kol aplankysite visus mazgus:
- Raskite nelankytą mazgą su mažiausiu žinomu atstumu.
- Atnaujinkite dabartinio mazgo nelankytų kaimynų atstumus.
- Pažymėkite dabartinį mazgą kaip aplankytą.
Sudėtingumo analizė:
- Laiko sudėtingumas: O(V^2) blogiausiu atveju, kur V yra viršūnių skaičius. Tai gali būti patobulinta iki O(V^2) su tam tikrais optimizavimais.
- Pagalbinė erdvė: O(V), kur V – viršūnių skaičius, o E – kraštinių skaičius grafe.
Dijkstra algoritmai vs Bellman-Ford algoritmas
Dijkstros algoritmas ir Bellman-Ford algoritmas Abu yra naudojami norint rasti trumpiausią kelią svertiniame grafike, tačiau jie turi keletą pagrindinių skirtumų. Štai pagrindiniai Dijkstra algoritmo ir Bellman-Ford algoritmo skirtumai:
| Ypatybė: | Dijkstra's | Belmanas Fordas |
|---|---|---|
| Optimizavimas | optimizuotas rasti trumpiausią kelią tarp vieno šaltinio mazgo ir visų kitų mazgų grafike su neneigiamais kraštų svoriais | Bellman-Ford algoritmas yra optimizuotas ieškant trumpiausio kelio tarp vieno šaltinio mazgo ir visų kitų mazgų grafike su neigiamais kraštų svoriais. |
| Atsipalaidavimas | Dijkstra algoritmas naudoja godų metodą, kai pasirenka mazgą su mažiausiu atstumu ir atnaujina savo kaimynus | Bellman-Ford algoritmas atpalaiduoja visas kiekvienos iteracijos briaunas, atnaujindamas kiekvieno mazgo atstumą, atsižvelgdamas į visus galimus kelius į tą mazgą |
| Laiko sudėtingumas | Dijkstra algoritmo laiko sudėtingumas yra O(V^2) tankiam grafui ir O(E log V) retam grafikui, kur V yra viršūnių skaičius, o E yra grafo briaunų skaičius. | Bellman-Ford algoritmo laiko sudėtingumas yra O(VE), kur V yra viršūnių skaičius, o E yra grafo briaunų skaičius. |
| Neigiami svoriai | Dijkstra algoritmas neveikia su grafikais, kurių kraštų svoriai yra neigiami, nes daroma prielaida, kad visi briaunų svoriai yra neneigiami. | Bellman-Ford algoritmas gali apdoroti neigiamus kraštų svorius ir aptikti neigiamo svorio ciklus grafike. |
Dijkstros algoritmas prieš Floydo-Warshall algoritmą
Dijkstros algoritmas ir Floydo-Warshall algoritmas Abu yra naudojami norint rasti trumpiausią kelią svertiniame grafike, tačiau jie turi keletą pagrindinių skirtumų. Štai pagrindiniai Dijkstra algoritmo ir Floydo-Warshall algoritmo skirtumai:
| Ypatybė: | Dijkstra's | Floydo-Warshall algoritmas |
|---|---|---|
| Optimizavimas | Optimizuotas norint rasti trumpiausią kelią tarp vieno šaltinio mazgo ir visų kitų mazgų grafike su neneigiamais kraštų svoriais | Floydo-Warshall algoritmas yra optimizuotas norint rasti trumpiausią kelią tarp visų grafiko mazgų porų. |
| Technika | Dijkstra algoritmas yra vieno šaltinio trumpiausio kelio algoritmas, kuris naudoja godų metodą ir apskaičiuoja trumpiausią kelią nuo šaltinio mazgo iki visų kitų grafiko mazgų. | Kita vertus, Floydo-Warshall algoritmas yra visų porų trumpiausio kelio algoritmas, kuris naudoja dinaminį programavimą, kad apskaičiuotų trumpiausią kelią tarp visų grafiko mazgų porų. |
| Laiko sudėtingumas | Dijkstra algoritmo laiko sudėtingumas yra O(V^2) tankiam grafui ir O(E log V) retam grafikui, kur V yra viršūnių skaičius, o E yra grafo briaunų skaičius. | Kita vertus, Floydo-Warshall algoritmas yra visų porų trumpiausio kelio algoritmas, kuris naudoja dinaminį programavimą, kad apskaičiuotų trumpiausią kelią tarp visų grafiko mazgų porų. |
| Neigiami svoriai | Dijkstra algoritmas neveikia su grafikais, kurių kraštų svoriai yra neigiami, nes daroma prielaida, kad visi briaunų svoriai yra neneigiami. | Kita vertus, Floydo-Warshall algoritmas yra visų porų trumpiausio kelio algoritmas, kuris naudoja dinaminį programavimą, kad apskaičiuotų trumpiausią kelią tarp visų grafiko mazgų porų. |
Dijkstros algoritmas prieš A* algoritmą
Dijkstros algoritmas ir A* algoritmas Abu yra naudojami norint rasti trumpiausią kelią svertiniame grafike, tačiau jie turi keletą pagrindinių skirtumų. Štai pagrindiniai Dijkstra algoritmo ir A* algoritmo skirtumai:
| Ypatybė: | A* Algoritmas | |
|---|---|---|
| Paieškos technika | Optimizuotas norint rasti trumpiausią kelią tarp vieno šaltinio mazgo ir visų kitų mazgų grafike su neneigiamais kraštų svoriais | A* algoritmas yra informuotas paieškos algoritmas, kuris naudoja euristinę funkciją, kad nukreiptų paiešką link tikslo mazgo. |
| Euristinė funkcija | Dijkstra algoritmas, nenaudoja jokios euristinės funkcijos ir atsižvelgia į visus grafiko mazgus. | A* algoritmas naudoja euristinę funkciją, kuri įvertina atstumą nuo dabartinio mazgo iki tikslo mazgo. Ši euristinė funkcija yra leistina, tai reiškia, kad ji niekada nepervertina tikrojo atstumo iki tikslo mazgo |
| Laiko sudėtingumas | Dijkstra algoritmo laiko sudėtingumas yra O(V^2) tankiam grafui ir O(E log V) retam grafikui, kur V yra viršūnių skaičius, o E yra kraštinių skaičius grafe. | A* algoritmo laiko sudėtingumas priklauso nuo euristinės funkcijos kokybės. |
| Taikymas | Dijkstra algoritmas naudojamas daugelyje programų, tokių kaip maršruto algoritmai, GPS navigacijos sistemos ir tinklo analizė | . A* algoritmas dažniausiai naudojamas kelio nustatymo ir grafiko perėjimo problemoms, tokioms kaip vaizdo žaidimai, robotika ir planavimo algoritmai. |
Dijkstra algoritmo praktikos problemos:
- Dijkstra trumpiausio kelio algoritmas | Godus Algo-7
- Dijkstra algoritmas gretimų vietų sąrašui pateikti | Godus Algo-8
- Dijkstra algoritmas – prioritetinė eilė ir masyvo įgyvendinimas
- Dijkstra trumpiausio kelio algoritmas, naudojant rinkinį STL
- Dijkstra trumpiausio kelio algoritmas naudojant STL C++
- Dijkstra trumpiausio kelio algoritmas, naudojant STL priority_queue
- Dijkstra trumpiausio kelio algoritmas naudojant matricą C++
- Dijkstra algoritmas, skirtas vieno šaltinio trumpiausiam keliui DAG
- Dijkstros algoritmas naudojant Fibonacci Heap
- Dijkstra trumpiausio kelio algoritmas nukreiptam grafikui su neigiamais svoriais
- Kelių spausdinimas Dijkstra trumpiausio kelio algoritmu
- Dijkstra trumpiausio kelio algoritmas su prioritetine eile Java




