V tem članku bomo razpravljali o enem najpogosteje znanih algoritmov najkrajše poti, tj. Dijkstrovem algoritmu najkrajše poti, ki ga je leta 1956 razvil nizozemski računalniški znanstvenik Edsger W. Dijkstra. Poleg tega bomo naredili analizo kompleksnosti za ta algoritem in tudi poglejte, kako se razlikuje od drugih algoritmov najkrajše poti.
Kazalo
- Dijkstrajev algoritem
- Potreba po Dijkstrinem algoritmu (namen in primeri uporabe)
- Ali lahko Dijkstrajev algoritem deluje na usmerjenih in neusmerjenih grafih?
- Algoritem za Dijkstrajev algoritem
- Kako deluje Dijkstrajev algoritem?
- Psevdo koda za Dijkstrajev algoritem
- Implementacija Dijkstrinega algoritma:
- Dijkstrovi algoritmi proti algoritmu Bellman-Ford
- Dijkstrajev algoritem proti Floyd-Warshallovemu algoritmu
- Dijkstrajev algoritem proti algoritmu A*
- Vadbene naloge na Dijkstrovem algoritmu
- Zaključek:

Dijkstrajev algoritem:
Dijkstrajev algoritem je priljubljen algoritem za reševanje številnih problemov najkrajše poti z enim samim virom, ki imajo nenegativno utež robov v grafih, tj. iskanje najkrajše razdalje med dvema vozliščema na grafu. Zamislil si ga je nizozemski računalničar Edsger W. Dijkstra leta 1956.
Algoritem vzdržuje niz obiskanih točk in niz neobiskanih točk. Začne se pri izvorni točki in iterativno izbere neobiskano točko z najmanjšo poskusno razdaljo od vira. Nato obišče sosede tega vozlišča in posodobi njihove poskusne razdalje, če najde krajšo pot. Ta proces se nadaljuje, dokler ni dosežena ciljna točka ali dokler niso obiskane vse dosegljive točke.
Potreba po Dijkstrinem algoritmu (namen in primeri uporabe)
Potreba po Dijkstrinem algoritmu se pojavi v številnih aplikacijah, kjer je iskanje najkrajše poti med dvema točkama ključnega pomena.
Na primer , Uporablja se lahko v usmerjevalnih protokolih za računalniška omrežja in ga uporabljajo tudi zemljevidni sistemi za iskanje najkrajše poti med začetno točko in ciljem (kot je razloženo v Kako deluje Google Maps? )
Ali lahko Dijkstrajev algoritem deluje na usmerjenih in neusmerjenih grafih?
ja , lahko Dijkstrav algoritem deluje tako na usmerjenih grafih kot tudi na neusmerjenih grafih, saj je ta algoritem zasnovan za delo na kateri koli vrsti grafa, če izpolnjuje zahteve glede nenegativnih uteži robov in povezanosti.
- V usmerjenem grafu, vsak rob ima smer, ki označuje smer potovanja med vozlišči, ki jih povezuje rob. V tem primeru algoritem pri iskanju najkrajše poti sledi smeri robov.
- V neusmerjenem grafu, robovi nimajo smeri in algoritem lahko premika tako naprej kot nazaj vzdolž robov, ko išče najkrajšo pot.
Algoritem za Dijkstrajev algoritem:
- Izvorno vozlišče označite s trenutno razdaljo 0, ostalo pa z neskončnostjo.
- Nastavite neobiskano vozlišče z najmanjšo trenutno razdaljo kot trenutno vozlišče.
- Za vsakega soseda N trenutnega vozlišča doda trenutno razdaljo sosednjega vozlišča s težo roba, ki povezuje 0->1. Če je manjša od trenutne razdalje vozlišča, jo nastavite kot novo trenutno razdaljo N.
- Trenutno vozlišče 1 označite kot obiskano.
- Pojdite na 2. korak, če obstajajo neobiskana vozlišča.
Kako deluje Dijkstrajev algoritem?
Oglejmo si, kako deluje Dijkstrajev algoritem s spodnjim primerom:
Dijkstrajev algoritem bo ustvaril najkrajšo pot od vozlišča 0 do vseh drugih vozlišč v grafu.
Razmislite o spodnjem grafu:
Dijkstrajev algoritem
Algoritem bo ustvaril najkrajšo pot od vozlišča 0 do vseh drugih vozlišč v grafu.
Za ta graf bomo predpostavili, da teža robov predstavlja razdaljo med dvema vozliščema.
branje datotek jsonKot lahko vidimo, imamo najkrajšo pot od
Vozlišče 0 do vozlišče 1, od
Vozlišče 0 do vozlišče 2, od
Vozlišče 0 do vozlišče 3, od
Vozlišče 0 do vozlišče 4, od
Vozlišče 0 do vozlišče 6.Na začetku imamo niz virov, navedenih spodaj:
seznam držav
- Razdalja od izvornega vozlišča do samega sebe je 0. V tem primeru je izvorno vozlišče 0.
- Razdalja od izvornega vozlišča do vseh drugih vozlišč ni znana, zato jih vse označimo kot neskončne.
Primer: 0 -> 0, 1-> ∞,2-> ∞,3-> ∞,4-> ∞,5-> ∞,6-> ∞.
- imeli bomo tudi niz neobiskanih elementov, ki bodo sledili neobiskanim ali neoznačenim vozliščem.
- Algoritem se bo zaključil, ko bodo poti dodana vsa vozlišča, označena kot obiskana, in razdalja med njimi. Neobiskana vozlišča:- 0 1 2 3 4 5 6.
Korak 1: Začnite od vozlišča 0 in označite vozlišče kot obiskano, saj lahko preverite spodnjo sliko. Obiskano vozlišče je označeno rdeče.
Dijkstrajev algoritem
2. korak: Preverite sosednja vozlišča, zdaj moramo izbrati (izberite vozlišče1 z razdaljo 2 ali izberite vozlišče 2 z razdaljo 6) in izberite vozlišče z najmanjšo razdaljo. V tem koraku Vozlišče 1 je najmanjša razdalja do sosednjega vozlišča, zato ga označite kot obiskanega in seštejte razdaljo.
Razdalja: vozlišče 0 -> vozlišče 1 = 2
Dijkstrajev algoritem
3. korak: Nato se pomaknite naprej in poiščite sosednje vozlišče, ki je vozlišče 3, zato ga označite kot obiskano in seštejte razdaljo. Zdaj bo razdalja:
Razdalja: vozlišče 0 -> vozlišče 1 -> vozlišče 3 = 2 + 5 = 7
Dijkstrajev algoritem
4. korak: Spet imamo dve možnosti za sosednja vozlišča (ali lahko izberemo vozlišče 4 z razdaljo 10 ali lahko izberemo vozlišče 5 z razdaljo 15), zato izberite vozlišče z najmanjšo razdaljo. V tem koraku Vozlišče 4 je najmanjša razdalja do sosednjega vozlišča, zato ga označite kot obiskanega in seštejte razdaljo.
Razdalja: vozlišče 0 -> vozlišče 1 -> vozlišče 3 -> vozlišče 4 = 2 + 5 + 10 = 17
Dijkstrajev algoritem
5. korak: Ponovno se pomaknite naprej in preverite sosednje vozlišče, ki je Vozlišče 6 , zato ga označite kot obiskano in seštejte razdaljo, Sedaj bo razdalja:
Razdalja: vozlišče 0 -> vozlišče 1 -> vozlišče 3 -> vozlišče 4 -> vozlišče 6 = 2 + 5 + 10 + 2 = 19
Dijkstrajev algoritem
Torej je najkrajša razdalja od izvornega vrha 19, kar je optimalno
Psevdo koda za Dijkstrajev algoritem
funkcija Dijkstra (graf, vir):
// Inicializiraj razdalje do vseh vozlišč kot neskončnost in do izvornega vozlišča kot 0.razdalje = zemljevid (vsa vozlišča -> neskončnost)
razdalje = 0
// Inicializirajte prazen nabor obiskanih vozlišč in prednostno čakalno vrsto za sledenje vozliščem, ki jih želite obiskati.
obiskano = prazen niz
čakalna vrsta = nova PriorityQueue()
queue.enqueue(vir, 0)// Zanka, dokler niso obiskana vsa vozlišča.
medtem ko čakalna vrsta ni prazna:
// Odstrani vozlišče z najmanjšo razdaljo od prednostne čakalne vrste.
trenutno = queue.dequeue()// Če je bilo vozlišče že obiskano, ga preskočite.
če je trenutno obiskano:
nadaljevatijavac ni prepoznan// Označi vozlišče kot obiskano.
visited.add(trenutno)// Preverite vsa sosednja vozlišča, da vidite, ali je treba posodobiti njihove razdalje.
za soseda v Graph.neighbors(trenutno):
// Izračunajte okvirno razdaljo do soseda skozi trenutno vozlišče.
tentative_distance = distances[current] + Graph.distance(trenutna, sosed)// Če je pogojna razdalja manjša od trenutne razdalje do soseda, posodobite razdaljo.
če pogojna_razdalja
razdalje[sosed] = pogojna_razdalja// Soseda postavi v čakalno vrsto z njegovo novo razdaljo, ki bo upoštevana za obisk v prihodnosti.
queue.enqueue(sosed, razdalje[sosed])// Vrne izračunane razdalje od vira do vseh drugih vozlišč v grafu.
povratne razdalje
Implementacija Dijkstrinega algoritma:
Obstaja več načinov za implementacijo Dijkstrinega algoritma, vendar so najpogostejši:
- Prednostna čakalna vrsta (izvedba na podlagi kopice):
- Izvedba na podlagi polja:
1. Dijkstrajev algoritem najkrajše poti z uporabo priority_queue (kup)
V tej izvedbi nam je podan graf in izvorna točka v grafu, ki najde najkrajše poti od izvora do vseh točk v danem grafu.
primer:
Vnos: Vir = 0
Primer
Izhod: Vertex
Oddaljenost vozlišča od vira
pokaži skrite aplikacije0 -> 0
1 -> 2
2 -> 6
3 -> 7
4 -> 17
5 -> 22
6 -> 19
Spodaj je algoritem, ki temelji na zgornji zamisli:
- Inicializirajte vrednosti razdalje in prednostno čakalno vrsto.
- Vstavite izvorno vozlišče v prednostno čakalno vrsto z razdaljo 0.
- Medtem ko prednostna čakalna vrsta ni prazna:
- Izvlecite vozlišče z najmanjšo razdaljo iz prednostne čakalne vrste.
- Posodobi razdalje svojih sosedov, če najde krajšo pot.
- V prednostno čakalno vrsto vstavite posodobljene sosede.
Spodaj je C++ implementacija zgornjega pristopa:
C++ // Program to find Dijkstra's shortest path using // priority_queue in STL #include using namespace std; #define INF 0x3f3f3f3f // iPair ==>Integer Pair typedef par iPair; // Ta razred predstavlja usmerjen graf z uporabo // seznama sosednosti reprezentančni razred Graph { int V; // Število tock // V uteženem grafu moramo shraniti točko // in par uteži za vsak seznam robov>* adj; javno: Graf(int V); // Konstruktor // funkcija za dodajanje roba grafu void addEdge(int u, int v, int w); // natisne najkrajšo pot iz s void shortestPath(int s); }; // Dodeli pomnilnik za seznam sosednosti Graph::Graph(int V) { this->V = V; adj = nov seznam [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)); } // Natisne najkrajše poti od src do vseh drugih točk void Graph::shortestPath(int src) { // Ustvari prednostno čakalno vrsto za shranjevanje točk, ki // so v predobdelavi. To je čudna sintaksa v C++. // Glejte spodnjo povezavo za podrobnosti te sintakse // https://www.techcodeview.com priority_queue , večji > pq; // Ustvarite vektor za razdalje in inicializirajte vse // razdalje kot neskončni (INF) vektor dist(V, INF); // Vstavi sam vir v prednostno čakalno vrsto in inicializira // njegovo razdaljo kot 0. pq.push(make_pair(0, src)); dist[src] = 0; /* Vrtenje v zanko, dokler prednostna čakalna vrsta ne postane prazna (ali vse razdalje niso dokončane) */ while (!pq.empty()) { // Prva točka v paru je najmanjša razdalja // točka, ekstrahirajte jo iz prednostne čakalne vrste. // oznaka vozlišča je shranjena v drugem paru (to // je treba storiti tako, da ohranimo // razvrščeno razdaljo med vozlišči (razdalja mora biti prvi element // v paru) int u = pq.top().second; pq.pop(); // 'i' se uporablja za pridobitev vseh sosednjih točk // seznama točk>::iterator i; for (i = adj[u].begin(); i != adj[u].end(); ++i) { // Pridobi oznako vozlišča in težo trenutnega // sosednjega u. int v = (*i).prvi; int teža = (*i).drugo; // Če je skrajšana pot do v skozi u. if (dist[v]> dist[u] + teža) { // Posodabljanje razdalje v dist[v] = dist[u] + teža; pq.push(make_pair(dist[v], v)); } } } // Natisni najkrajše razdalje, shranjene v dist[] printf('Razdalja vozlišča od vira
'); za (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 razdalja; javno vozlišče (int v, int razdalja) { this.v = v; this.distance = razdalja; } @Override public int compareTo(Node n) { if (this.distance<= n.distance) { return -1; } else { return 1; } } } static int[] dijkstra( int V, ArrayList >> adj, int S) { boolean [] obiskan = nov boolean [V]; HashMap zemljevid = nov HashMap(); PriorityQueueq = nova PriorityQueue(); map.put(S, novo vozlišče(S, 0)); q.add(novo vozlišče(S, 0)); medtem ko (!q.isEmpty()) { Vozlišče n = q.poll(); int v = n.v; int razdalja = n.distance; obiskano [v] = res; ArrayList > adjList = adj.get(v); za (ArrayList adjLink : adjList) { if (visited[adjLink.get(0)] == false) { if (!map.containsKey(adjLink.get(0))) { map.put( adjLink.get(0), novo vozlišče (v, razdalja + adjLink.get(1))); } else { Vozlišče sn = map.get(adjLink.get(0)); če (razdalja + 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 >> map = new 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 }; za (int i = 0; i< E; i++) { ArrayList rob = nov ArrayList(); edge.add(v[i]); edge.add(w[i]); ArrayList > adjList; if (!map.containsKey(u[i])) { adjList = new ArrayList(); } else { adjList = map.get(u[i]); } adjList.add(rob); map.put(u[i], adjList); ArrayList edge2 = nov ArrayList(); edge2.add(u[i]); edge2.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); } za (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; // Konstruktor public Graph(int v) { V = v; adj = nov seznam>[ v ]; za (int i = 0; i< v; ++i) adj[i] = new List>(); } // funkcija za dodajanje roba grafu public void addEdge(int u, int v, int w) { adj[u].Add(Tuple.Create(v, w)); adj[v].Add(Tuple.Create(u, w)); } // natisne najkrajšo pot iz public void shortestPath(int s) { // Ustvari prednostno čakalno vrsto za shranjevanje točk, // ki so v predprocesiranju. var pq = nova PriorityQueue>(); // Ustvari vektor za razdalje in inicializiraj vse // razdalje kot neskončne (INF) var dist = new int[V]; za (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] + teža) { // Posodabljanje razdalje v dist[v] = dist[u] + teža; pq.Enqueue(Tuple.Create(dist[v], v)); } } } // Natisni najkrajše razdalje, shranjene v dist[] Console.WriteLine('Razdalja vozlišča od vira'); za (int i = 0; i< V; ++i) Console.WriteLine('{0} {1}', i, dist[i]); } } public class PriorityQueue{ zasebni seznam samo za branje_podatki; zasebna primerjava samo za branje_primerjano; public PriorityQueue(): this(Compare.Privzeto) { } public PriorityQueue(IComparerprimerjaj): this(compare.Compare) { } public PriorityQueue(Comparisonprimerjava) { _data = nov seznam(); _compare = primerjava; } public void Enqueue(T item) { _data.Add(item); var childIndex = _data.Count - 1; medtem ko (childIndex> 0) { var parentIndex = (childIndex - 1) / 2; if (_compare(_data[childIndex], _data[parentIndex])>= 0) break; T tmp = _data[childIndex]; _podatki[childIndex] = _data[parentIndex]; _podatki[parentIndex] = tmp; childIndex = parentIndex; } } public T Dequeue() { // predvideva, da pq ni prazen; do klicne kode var lastElement = _data.Count - 1; var frontItem = _data[0]; _podatki[0] = _podatki[zadnjiElement]; _data.RemoveAt(lastElement); --lastElement; var parentIndex = 0; medtem ko (true) { var childIndex = parentIndex * 2 + 1; if (childIndex> lastElement) break; // Konec drevesa var rightChild = childIndex + 1; če (desno Otrok<= 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.prioriteta - b.prioriteta); } dequeue() { if (this.isEmpty()) { return null; } return this.queue.shift().element; } isEmpty() { return this.queue.length === 0; } } class Graph { konstruktor(V) { this.V = V; this.adj = nova matrika (V); za (naj bo 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();> Končni odgovor:

Izhod
Analiza kompleksnosti Dijkstra algoritma :
- Časovna zahtevnost: O((V + E) log V) , kjer je V število oglišč in E število robov.
- Pomožni prostor: O(V), kjer je V število vozlišč in E število robov v grafu.
2.Implementacija Dijkstrinega algoritma na osnovi nizov (naivni pristop):
Dijkstrajev algoritem je mogoče implementirati tudi z uporabo nizov brez uporabe prednostne čakalne vrste. Ta izvedba je preprosta, vendar je lahko manj učinkovita, zlasti na velikih grafih.
Algoritem poteka na naslednji način:
- Inicializirajte matriko za shranjevanje razdalj od vira do vsakega vozlišča.
- Označite vsa vozlišča kot neobiskana.
- Nastavite razdaljo do izvornega vozlišča na 0 in neskončnost za vsa druga vozlišča.
- Ponavljajte, dokler ne obiščete vseh vozlišč:
- Poiščite neobiskano vozlišče z najmanjšo znano razdaljo.
- Za trenutno vozlišče posodobite razdalje njegovih neobiskanih sosedov.
- Trenutno vozlišče označite kot obiskano.
Analiza kompleksnosti:
- Časovna zapletenost: O(V^2) v najslabšem primeru, kjer je V število oglišč. To je mogoče z nekaj optimizacijami izboljšati na O(V^2).
- Pomožni prostor: O(V), kjer je V število vozlišč in E število robov v grafu.
Dijkstrovi algoritmi proti algoritmu Bellman-Ford
Dijkstrajev algoritem in Bellman-Fordov algoritem oba se uporabljata za iskanje najkrajše poti v uteženem grafu, vendar imata nekaj ključnih razlik. Tu so glavne razlike med Dijkstrinim algoritmom in Bellman-Fordovim algoritmom:
| funkcija: | Dijkstra je | Bellman Ford |
|---|---|---|
| Optimizacija | optimizirano za iskanje najkrajše poti med enim izvornim vozliščem in vsemi drugimi vozlišči v grafu z nenegativnimi utežmi robov | Bellman-Fordov algoritem je optimiziran za iskanje najkrajše poti med enim izvornim vozliščem in vsemi drugimi vozlišči v grafu z negativnimi utežmi robov. |
| Sprostitev | Dijkstrajev algoritem uporablja požrešen pristop, kjer izbere vozlišče z najmanjšo razdaljo in posodobi njegove sosede | Bellman-Fordov algoritem sprosti vse robove v vsaki ponovitvi, pri čemer posodobi razdaljo vsakega vozlišča z upoštevanjem vseh možnih poti do tega vozlišča |
| Časovna zapletenost | Dijkstrajev algoritem ima časovno kompleksnost O(V^2) za gost graf in O(E log V) za redek graf, kjer je V število vozlišč in E število robov v grafu. | Bellman-Fordov algoritem ima časovno kompleksnost O(VE), kjer je V število vozlišč in E število robov v grafu. |
| Negativne uteži | Dijkstrajev algoritem ne deluje z grafi, ki imajo negativne uteži robov, saj predpostavlja, da so vse uteži robov nenegativne. | Bellman-Fordov algoritem lahko obravnava negativne uteži robov in zazna cikle negativnih uteži v grafu. |
Dijkstrajev algoritem proti Floyd-Warshallovemu algoritmu
Dijkstrajev algoritem in Floyd-Warshallov algoritem oba se uporabljata za iskanje najkrajše poti v uteženem grafu, vendar imata nekaj ključnih razlik. Tu so glavne razlike med Dijkstrinim algoritmom in Floyd-Warshallovim algoritmom:
| funkcija: | Dijkstra je | Floyd-Warshallov algoritem |
|---|---|---|
| Optimizacija | Optimizirano za iskanje najkrajše poti med enim izvornim vozliščem in vsemi drugimi vozlišči v grafu z nenegativnimi utežmi robov | Algoritem Floyd-Warshall je optimiziran za iskanje najkrajše poti med vsemi pari vozlišč v grafu. |
| Tehnika | Dijkstrajev algoritem je algoritem najkrajše poti z enim virom, ki uporablja požrešen pristop in izračuna najkrajšo pot od izvornega vozlišča do vseh drugih vozlišč v grafu. | Floyd-Warshallov algoritem pa je algoritem najkrajše poti z vsemi pari, ki uporablja dinamično programiranje za izračun najkrajše poti med vsemi pari vozlišč v grafu. |
| Časovna zapletenost | Dijkstrajev algoritem ima časovno kompleksnost O(V^2) za gost graf in O(E log V) za redek graf, kjer je V število vozlišč in E število robov v grafu. | Floyd-Warshallov algoritem pa je algoritem najkrajše poti z vsemi pari, ki uporablja dinamično programiranje za izračun najkrajše poti med vsemi pari vozlišč v grafu. |
| Negativne uteži | Dijkstrajev algoritem ne deluje z grafi, ki imajo negativne uteži robov, saj predpostavlja, da so vse uteži robov nenegativne. | Floyd-Warshallov algoritem pa je algoritem najkrajše poti z vsemi pari, ki uporablja dinamično programiranje za izračun najkrajše poti med vsemi pari vozlišč v grafu. |
Dijkstrajev algoritem proti algoritmu A*
Dijkstrajev algoritem in A* algoritem oba se uporabljata za iskanje najkrajše poti v uteženem grafu, vendar imata nekaj ključnih razlik. Tu so glavne razlike med Dijkstrovim algoritmom in algoritmom A*:
| funkcija: | A* Algoritem | |
|---|---|---|
| Tehnika iskanja | Optimizirano za iskanje najkrajše poti med enim izvornim vozliščem in vsemi drugimi vozlišči v grafu z nenegativnimi utežmi robov | Algoritem A* je informiran iskalni algoritem, ki uporablja hevristično funkcijo za vodenje iskanja proti ciljnemu vozlišču. |
| Hevristična funkcija | Dijkstrajev algoritem ne uporablja nobene hevristične funkcije in upošteva vsa vozlišča v grafu. | Algoritem A* uporablja hevristično funkcijo, ki oceni razdaljo od trenutnega vozlišča do ciljnega vozlišča. Ta hevristična funkcija je dopustna, kar pomeni, da nikoli ne preceni dejanske razdalje do ciljnega vozlišča |
| Časovna zapletenost | Dijkstrajev algoritem ima časovno kompleksnost O(V^2) za gost graf in O(E log V) za redek graf, kjer je V število vozlišč in E število robov v grafu. | Časovna zahtevnost algoritma A* je odvisna od kakovosti hevristične funkcije. |
| Aplikacija | Dijkstrajev algoritem se uporablja v številnih aplikacijah, kot so algoritmi za usmerjanje, navigacijski sistemi GPS in analiza omrežja | . Algoritem A* se običajno uporablja pri težavah iskanja poti in prehoda grafov, kot so video igre, robotika in algoritmi načrtovanja. |
Vadbene naloge na Dijkstrovem algoritmu:
- Dijkstrajev algoritem najkrajše poti | Pohlepni Algo-7
- Dijkstrajev algoritem za predstavitev seznama sosednosti | Pohlepni Algo-8
- Dijkstrajev algoritem – implementacija prednostne čakalne vrste in polja
- Dijkstrajev algoritem najkrajše poti z uporabo nastavljenega v STL
- Dijkstrajev algoritem najkrajše poti z uporabo STL v C++
- Dijkstrajev algoritem najkrajše poti z uporabo priority_queue STL
- Dijkstrajev algoritem najkrajše poti z uporabo matrike v C++
- Dijkstrajev algoritem za najkrajšo pot enega vira v DAG
- Dijkstrajev algoritem z uporabo Fibonaccijeve kopice
- Dijkstrajev algoritem najkrajše poti za usmerjen graf z negativnimi utežmi
- Tiskanje poti v Dijkstrovem algoritmu najkrajše poti
- Dijkstrajev algoritem najkrajše poti s prednostno čakalno vrsto v Javi




