logo

Wat is het algoritme van Dijkstra? | Inleiding tot het kortste padalgoritme van Dijkstra

In dit artikel bespreken we een van de meest bekende algoritmen voor het kortste pad, namelijk Dijkstra's Shortest Path Algorithm, ontwikkeld door de Nederlandse computerwetenschapper Edsger W. Dijkstra in 1956. Bovendien zullen we een complexiteitsanalyse voor dit algoritme uitvoeren en ook kijk hoe het verschilt van andere kortste-padalgoritmen.

Inhoudsopgave

dijkstra-algoritme-(1)



Het algoritme van Dijkstra:

Het algoritme van Dijkstra is een populair algoritme voor het oplossen van veel kortste-padproblemen met één bron met een niet-negatief randgewicht in de grafieken, dat wil zeggen, het is om de kortste afstand tussen twee hoekpunten in een grafiek te vinden. Het is bedacht door een Nederlandse computerwetenschapper Edsger W. Dijkstra in 1956.

Het algoritme houdt een reeks bezochte hoekpunten en een reeks niet-bezochte hoekpunten bij. Het begint bij het bronpunt en selecteert iteratief het niet-bezochte hoekpunt met de kleinste voorlopige afstand tot de bron. Vervolgens bezoekt het de buren van dit hoekpunt en werkt hun voorlopige afstanden bij als er een korter pad wordt gevonden. Dit proces gaat door totdat het bestemmingspunt is bereikt of alle bereikbare hoekpunten zijn bezocht.

Behoefte aan het algoritme van Dijkstra (doel en use-cases)

De behoefte aan het algoritme van Dijkstra ontstaat in veel toepassingen waarbij het vinden van het kortste pad tussen twee punten cruciaal is.

Bijvoorbeeld Het kan worden gebruikt in de routeringsprotocollen voor computernetwerken en ook worden gebruikt door kaartsystemen om het kortste pad te vinden tussen het startpunt en de bestemming (zoals uitgelegd in Hoe werkt Google Maps? )

Kan het algoritme van Dijkstra werken op zowel gerichte als ongerichte grafieken?

Ja kan het algoritme van Dijkstra zowel op gerichte grafieken als op ongerichte grafieken werken, aangezien dit algoritme is ontworpen om op elk type grafiek te werken, zolang het maar voldoet aan de vereisten van niet-negatieve randgewichten en verbondenheid.

  • In een gerichte graaf geldt elke rand heeft een richting, die de reisrichting aangeeft tussen de hoekpunten die door de rand zijn verbonden. In dit geval volgt het algoritme de richting van de randen bij het zoeken naar het kortste pad.
  • In een ongerichte grafiek, de randen hebben geen richting en het algoritme kan zowel voorwaarts als achterwaarts langs de randen bewegen bij het zoeken naar het kortste pad.

Algoritme voor het algoritme van Dijkstra:

  1. Markeer het bronknooppunt met een huidige afstand van 0 en de rest met oneindig.
  2. Stel het niet-bezochte knooppunt met de kleinste huidige afstand in als het huidige knooppunt.
  3. Voor elke buur telt N van het huidige knooppunt de huidige afstand van het aangrenzende knooppunt op met het gewicht van de rand die 0->1 verbindt. Als deze kleiner is dan de huidige afstand van Knooppunt, stelt u deze in als de nieuwe huidige afstand van N.
  4. Markeer het huidige knooppunt 1 als bezocht.
  5. Ga naar stap 2 als er knooppunten zijn die nog niet zijn bezocht.

Hoe werkt het algoritme van Dijkstra?

Laten we eens kijken hoe het algoritme van Dijkstra werkt met het onderstaande voorbeeld:

Het algoritme van Dijkstra genereert het kortste pad van knooppunt 0 naar alle andere knooppunten in de grafiek.

Beschouw de onderstaande grafiek:

Dijkstra

Het algoritme van Dijkstra

Het algoritme genereert het kortste pad van knooppunt 0 naar alle andere knooppunten in de grafiek.

Voor deze grafiek gaan we ervan uit dat het gewicht van de randen de afstand tussen twee knooppunten vertegenwoordigt.

snijd Java

Zoals we kunnen zien hebben we de kortste weg van:
Knooppunt 0 tot knooppunt 1, van
Knooppunt 0 tot knooppunt 2, van
Knooppunt 0 tot knooppunt 3, van
Knooppunt 0 tot knooppunt 4, van
Knooppunt 0 tot knooppunt 6.

In eerste instantie hebben we een reeks bronnen die hieronder worden gegeven:

  • De afstand van het bronknooppunt tot zichzelf is 0. In dit voorbeeld is het bronknooppunt 0.
  • De afstand van het bronknooppunt tot alle andere knooppunten is onbekend, dus markeren we ze allemaal als oneindig.

Voorbeeld: 0 -> 0, 1-> ∞,2-> ∞,3-> ∞,4-> ∞,5-> ∞,6-> ∞.

  • we hebben ook een reeks niet-bezochte elementen die niet-bezochte of ongemarkeerde knooppunten bijhouden.
  • Het algoritme wordt voltooid wanneer alle knooppunten die als bezocht zijn gemarkeerd en de afstand ertussen aan het pad zijn toegevoegd. Niet-bezochte knooppunten: - 0 1 2 3 4 5 6.

Stap 1: Begin vanaf knooppunt 0 en markeer knooppunt als bezocht, zoals u kunt zien in onderstaande afbeelding bezocht knooppunt is rood gemarkeerd.

Dijkstra

Het algoritme van Dijkstra

Stap 2: Controleer op aangrenzende knooppunten. Nu moeten we keuzes maken (kies knooppunt 1 met afstand 2 of kies knooppunt 2 met afstand 6) en kies knooppunt met minimale afstand. In deze stap Knooppunt 1 is de minimale afstand naast het knooppunt, dus markeer het als bezocht en tel de afstand op.

Afstand: Knooppunt 0 -> Knooppunt 1 = 2

Dijkstra

Het algoritme van Dijkstra

Stap 3: Ga dan verder en controleer of er een aangrenzend knooppunt is, dat knooppunt 3 is, dus markeer het als bezocht en tel de afstand op. Nu is de afstand:

Afstand: Knooppunt 0 -> Knooppunt 1 -> Knooppunt 3 = 2 + 5 = 7

Dijkstra

Het algoritme van Dijkstra

Stap 4: Opnieuw hebben we twee keuzes voor aangrenzende knooppunten (we kunnen knooppunt 4 kiezen met afstand 10 of we kunnen knooppunt 5 kiezen met afstand 15), dus kies knooppunt met minimale afstand. In deze stap Knooppunt 4 is de minimale afstand naast het knooppunt, dus markeer het als bezocht en tel de afstand op.

Afstand: Knooppunt 0 -> Knooppunt 1 -> Knooppunt 3 -> Knooppunt 4 = 2 + 5 + 10 = 17

Dijkstra

Het algoritme van Dijkstra

Stap 5: Nogmaals, ga vooruit en controleer of er een aangrenzend knooppunt is Knooppunt 6 , dus markeer het als bezocht en tel de afstand op. Nu wordt de afstand:

wat is $home linux

Afstand: Knooppunt 0 -> Knooppunt 1 -> Knooppunt 3 -> Knooppunt 4 -> Knooppunt 6 = 2 + 5 + 10 + 2 = 19

Dijkstra

Het algoritme van Dijkstra

De kortste afstand vanaf het bronpunt is dus 19, wat optimaal is

Pseudocode voor het algoritme van Dijkstra

functie Dijkstra(Grafiek, bron):
// Initialiseer afstanden naar alle knooppunten als oneindig, en naar het bronknooppunt als 0.

afstanden = kaart(alle knooppunten -> oneindig)

afstanden = 0

// Initialiseer een lege set bezochte knooppunten en een prioriteitswachtrij om bij te houden welke knooppunten moeten worden bezocht.
bezocht = lege set
wachtrij = nieuwe PriorityQueue()
wachtrij.enqueue(bron, 0)

wat is een speciaal karakter

// Loop totdat alle knooppunten zijn bezocht.
terwijl de wachtrij niet leeg is:
// Haal het knooppunt met de kleinste afstand uit de prioriteitswachtrij uit de wachtrij.
huidige = wachtrij.dequeue()

// Als het knooppunt al is bezocht, sla het dan over.
indien actueel in bezocht:
doorgaan

// Markeer het knooppunt als bezocht.
bezocht.add(huidig)

// Controleer alle aangrenzende knooppunten om te zien of hun afstanden moeten worden bijgewerkt.
voor buurman in Graph.neighbors(current):
// Bereken de voorlopige afstand tot de buurman via het huidige knooppunt.
tentative_distance = afstanden [huidig] + Graph.distance (huidig, buurman)

// Als de voorlopige afstand kleiner is dan de huidige afstand tot de buurman, update dan de afstand.
indien voorlopige_afstand
afstanden[buur] = voorlopige_afstand

// Zet de buurman in de wachtrij met zijn nieuwe afstand, zodat hij in de toekomst in aanmerking komt voor bezoek.
wachtrij.enqueue(buurman, afstanden[buurman])

// Retourneer de berekende afstanden van de bron naar alle andere knooppunten in de grafiek.
afstanden terug

Implementatie van Dijkstra’s algoritme:

Er zijn verschillende manieren om het algoritme van Dijkstra te implementeren, maar de meest voorkomende zijn:

  1. Prioriteitswachtrij (op heap gebaseerde implementatie):
  2. Array-gebaseerde implementatie:

1. Dijkstra's kortste pad-algoritme met behulp van prioriteit_queue (Heap)

In deze implementatie krijgen we een grafiek en een bronpunt in de grafiek, waarbij we de kortste paden van de bron naar alle hoekpunten in de gegeven grafiek vinden.

Voorbeeld:

Invoer: Bron = 0

Voorbeeld

tekenreeks naar char

Uitgang: Hoekpunt

Hoekpuntafstand vanaf de bron

0 -> 0
1 -> 2
2 -> 6
3 -> 7
4 -> 17
5 -> 22
6 -> 19

Hieronder vindt u het algoritme gebaseerd op het bovenstaande idee:

  • Initialiseer de afstandswaarden en de prioriteitswachtrij.
  • Plaats het bronknooppunt in de prioriteitswachtrij met afstand 0.
  • Terwijl de prioriteitswachtrij niet leeg is:
    • Extraheer het knooppunt met de minimale afstand tot de prioriteitswachtrij.
    • Update de afstanden van zijn buren als er een korter pad wordt gevonden.
    • Voeg bijgewerkte buren in de prioriteitswachtrij in.

Hieronder vindt u de C++-implementatie van de bovenstaande aanpak:

C++
// Program to find Dijkstra's shortest path using // priority_queue in STL #include  using namespace std; #define INF 0x3f3f3f3f // iPair ==>Geheel getal Paar typedef paar iPair; // Deze klasse vertegenwoordigt een gerichte grafiek met behulp van // representatieklasse van aangrenzende lijst Graph { int V; // Aantal hoekpunten // In een gewogen grafiek moeten we hoekpunten // en een gewichtspaar opslaan voor elke lijst met randen>* bijvoeglijk naamwoord; publiek: Grafiek(int V); // Constructor // functie om een ​​rand toe te voegen aan de grafiek void addEdge(int u, int v, int w);  // drukt het kortste pad af van s void shortestPath(int s); }; // Wijst geheugen toe voor de aangrenzende lijst Graph::Graph(int V) { this->V = V;  adj = nieuwe lijst [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)); } // Drukt de kortste paden af ​​van src naar alle andere hoekpunten void Graph::shortestPath(int src) {// Maak een prioriteitswachtrij om hoekpunten op te slaan die // worden voorbewerkt. Dit is een vreemde syntaxis in C++.  // Zie onderstaande link voor details van deze syntaxis // https://www.techcodeview.com prioriteit_queue , groter > pq;  // Maak een vector voor afstanden en initialiseer alle // afstanden als oneindige (INF) vector dist(V, INF);  // Plaats de bron zelf in de prioriteitswachtrij en initialiseer // de afstand ervan als 0. pq.push(make_pair(0, src));  dist[src] = 0;  /* Loopt totdat de prioriteitswachtrij leeg wordt (of alle afstanden zijn niet definitief) */ while (!pq.empty()) {/ // Het eerste hoekpunt in paar is de minimale afstand // hoekpunt, haal het uit de prioriteitswachtrij.  // hoekpuntlabel wordt opgeslagen als seconde van een paar (het // moet op deze manier worden gedaan om de hoekpunten // gesorteerde afstand te behouden (afstand moet het eerste item zijn // in paar) int u = pq.top().second; pq.pop(); // 'i' wordt gebruikt om alle aangrenzende hoekpunten van een // hoekpuntenlijst op te halen>::iterator ik;  for (i = adj[u].begin(); i != adj[u].end(); ++i) {// Haal het hoekpuntlabel op en het gewicht van de huidige // aangrenzend aan u.  int v = (*i).eerste;  int gewicht = (*i).seconde;  // Als er een kort pad is naar v via u.  if (dist[v]> dist[u] + gewicht) {// Afstand van v dist[v] = dist[u] + gewicht bijwerken;  pq.push(make_pair(dist[v], v));  } } } // Print de kortste afstanden opgeslagen in dist[] printf('Vertex Distance from Source
');  voor (int i = 0; ik< 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{  in TV;  int afstand;  openbaar knooppunt (int v, int afstand) { this.v = v;  deze.afstand = afstand;  } @Override public int CompareTo(Node n) { if (this.distance<= n.distance) {  return -1;  }  else {  return 1;  }  }  }  static int[] dijkstra(  int V,  ArrayList >> bijvoeglijk naamwoord, int S) { boolean[] bezocht = nieuwe boolean[V];  Hash kaart kaart = nieuwe HashMap();  Prioriteits-rijq = nieuwe PriorityQueue();  map.put(S, nieuw knooppunt(S, 0));  q.add(nieuw knooppunt(S, 0));  while (!q.isEmpty()) { Knooppunt n = q.poll();  int v = nv;  int afstand = n.afstand;  bezocht[v] = waar;  ArrayLijst > adjLijst = adj.get(v);  voor (ArrayList adjLink: adjList) { if (bezocht[adjLink.get(0)] == false) { if (!map.containsKey(adjLink.get(0))) { map.put( adjLink.get(0), nieuw knooppunt (v, afstand + adjLink.get(1)));  } else { Knooppunt sn = map.get(adjLink.get(0));  if (afstand + 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 = nieuwe ArrayList();  Hash kaart >> kaart = nieuwe 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 };  voor (int i = 0; ik< E; i++) {  ArrayList edge = nieuwe ArrayList();  rand.toevoegen(v[i]);  edge.add(w[i]);  ArrayLijst > adjLijst;  if (!map.containsKey(u[i])) { adjList = nieuwe ArrayList();  } anders { adjList = map.get(u[i]);  } adjList.add(rand);  map.put(u[i], adjLijst);  ArrayLijst edge2 = nieuwe ArrayList();  edge2.add(u[i]);  edge2.add(w[i]);  ArrayLijst > adjLijst2;  if (!map.containsKey(v[i])) { adjList2 = nieuwe ArrayList();  } anders { adjList2 = map.get(v[i]);  } adjList2.add(edge2);  map.put(v[i], adjList2);  } voor (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>[] bijvoeglijk naamwoord;  // Constructor openbare grafiek (int v) {V = v;  adj = nieuwe lijst>[v];  voor (int i = 0; ik< v; ++i)  adj[i] = new List>();  } // functie om een ​​rand toe te voegen aan de grafiek public void addEdge(int u, int v, int w) { adj[u].Add(Tuple.Create(v, w));  adj[v].Add(Tuple.Create(u, w));  } // print het kortste pad van s public void shortestPath(int s) {// Maak een prioriteitswachtrij om hoekpunten op te slaan die // worden voorbewerkt.  var pq = nieuwe PriorityQueue>();  // Maak een vector voor afstanden en initialiseer alles // afstanden als oneindig (INF) var dist = new int[V];  voor (int i = 0; ik< 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] + gewicht) {/ // Afstand van v bijwerken dist[v] = dist[u] + gewicht;  pq.Enqueue(Tuple.Create(dist[v], v));  } } } // Druk de kortste afstanden af ​​die zijn opgeslagen in dist[] Console.WriteLine('Vertex Distance from Source');  voor (int i = 0; ik< V; ++i)  Console.WriteLine('{0}		{1}', i, dist[i]);  } } public class PriorityQueue{ privé-lezenlijst_gegevens;  privé-lezen vergelijking_vergeleken;  public PriorityQueue(): this(Vergelijk.Default) { } public PriorityQueue(IComparervergelijk): this(vergelijk.Vergelijk) { } public PriorityQueue(Vergelijkingvergelijking) { _data = nieuwe lijst();  _vergelijk = vergelijking;  } public void Enqueue(T item) { _data.Add(item);  var childIndex = _data.Count - 1;  while (childIndex> 0) { var parentIndex = (childIndex - 1) / 2;  if (_compare(_data[childIndex], _data[parentIndex])>= 0) break;  T tmp = _data[kindIndex];  _data[kindIndex] = _data[ouderIndex];  _data[parentIndex] = tmp;  kindIndex = ouderIndex;  } } public T Dequeue() {// gaat ervan uit dat pq niet leeg is; tot aanroepcode var lastElement = _data.Count - 1;  var frontItem = _data[0];  _data[0] = _data[laatsteElement];  _data.RemoveAt(laatsteElement);  --laatsteElement;  var ouderIndex = 0;  while (true) { var childIndex = parentIndex * 2 + 1;  if (childIndex> lastElement) break; // Einde van boom var rightChild = childIndex + 1;  if (rightChild<= 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.prioriteit - b.prioriteit);  } dequeue() { if (this.isEmpty()) { return null;  } return this.queue.shift().element;  } isEmpty() { return this.queue.length === 0;  } } klasse Grafiek { constructor(V) { this.V = V;  this.adj = nieuwe Array(V);  voor (laat 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();>

Definitieve antwoord:

Uitvoer

Complexiteitsanalyse van het Dijkstra-algoritme :

  • Tijdcomplexiteit: O((V + E) log V) , waarbij V het aantal hoekpunten is en E het aantal randen.
  • Hulpruimte: O(V), waarbij V het aantal hoekpunten is en E het aantal randen in de grafiek.

2.Array-gebaseerde implementatie van Dijkstra’s algoritme (naïeve benadering):

Het algoritme van Dijkstra kan ook worden geïmplementeerd met behulp van arrays zonder gebruik te maken van een prioriteitswachtrij. Deze implementatie is eenvoudig, maar kan minder efficiënt zijn, vooral bij grote grafieken.

Het algoritme gaat als volgt te werk:

  • Initialiseer een array om de afstanden van de bron tot elk knooppunt op te slaan.
  • Markeer alle knooppunten als niet bezocht.
  • Stel de afstand tot het bronknooppunt in op 0 en oneindig voor alle andere knooppunten.
  • Herhaal dit totdat alle knooppunten zijn bezocht:
    • Zoek het niet-bezochte knooppunt met de kleinst bekende afstand.
    • Update voor het huidige knooppunt de afstanden van de niet-bezochte buren.
    • Markeer het huidige knooppunt als bezocht.

Complexiteitsanalyse:

  • Tijdcomplexiteit: O(V^2) in het ergste geval, waarbij V het aantal hoekpunten is. Dit kan met enkele optimalisaties worden verbeterd tot O(V^2).
  • Hulpruimte: O(V), waarbij V het aantal hoekpunten is en E het aantal randen in de grafiek.

Dijkstra's algoritmen versus Bellman-Ford-algoritme

Dijkstra's algoritme en Bellman-Ford-algoritme worden beide gebruikt om het kortste pad in een gewogen grafiek te vinden, maar ze hebben enkele belangrijke verschillen. Dit zijn de belangrijkste verschillen tussen het algoritme van Dijkstra en het Bellman-Ford-algoritme:

Functie:Dijkstra’sBellman Ford
Optimalisatiegeoptimaliseerd voor het vinden van het kortste pad tussen een enkel bronknooppunt en alle andere knooppunten in een grafiek met niet-negatieve randgewichtenHet Bellman-Ford-algoritme is geoptimaliseerd voor het vinden van het kortste pad tussen een enkel bronknooppunt en alle andere knooppunten in een grafiek met negatieve randgewichten.
OntspanningHet algoritme van Dijkstra gebruikt een hebzuchtige aanpak waarbij het het knooppunt met de kleinste afstand kiest en zijn buren bijwerkthet Bellman-Ford-algoritme versoepelt alle randen in elke iteratie, waarbij de afstand van elk knooppunt wordt bijgewerkt door alle mogelijke paden naar dat knooppunt te overwegen
TijdcomplexiteitHet algoritme van Dijkstra heeft een tijdscomplexiteit van O(V^2) voor een dichte grafiek en O(E log V) voor een dunne grafiek, waarbij V het aantal hoekpunten is en E het aantal randen in de grafiek.Het Bellman-Ford-algoritme heeft een tijdscomplexiteit van O(VE), waarbij V het aantal hoekpunten is en E het aantal randen in de grafiek.
Negatieve gewichtenHet algoritme van Dijkstra werkt niet met grafieken met negatieve randgewichten, omdat het ervan uitgaat dat alle randgewichten niet-negatief zijn.Het Bellman-Ford-algoritme kan omgaan met negatieve randgewichten en kan negatieve gewichtscycli in de grafiek detecteren.

Dijkstra's algoritme versus Floyd-Warshall-algoritme

Dijkstra's algoritme en Floyd-Warshall-algoritme worden beide gebruikt om het kortste pad in een gewogen grafiek te vinden, maar ze hebben enkele belangrijke verschillen. Hier zijn de belangrijkste verschillen tussen het algoritme van Dijkstra en het Floyd-Warshall-algoritme:

Functie:Dijkstra’sFloyd-Warshall-algoritme
OptimalisatieGeoptimaliseerd voor het vinden van het kortste pad tussen een enkel bronknooppunt en alle andere knooppunten in een grafiek met niet-negatieve randgewichtenHet Floyd-Warshall-algoritme is geoptimaliseerd voor het vinden van het kortste pad tussen alle paren knooppunten in een grafiek.
TechniekHet algoritme van Dijkstra is een algoritme voor het kortste pad uit één bron dat een hebzuchtige aanpak gebruikt en het kortste pad berekent van het bronknooppunt naar alle andere knooppunten in de grafiek.Het Floyd-Warshall-algoritme is daarentegen een algoritme met het kortste pad uit alle paren dat dynamische programmering gebruikt om het kortste pad tussen alle paren knooppunten in de grafiek te berekenen.
TijdcomplexiteitHet algoritme van Dijkstra heeft een tijdscomplexiteit van O(V^2) voor een dichte grafiek en O(E log V) voor een dunne grafiek, waarbij V het aantal hoekpunten is en E het aantal randen in de grafiek.Het Floyd-Warshall-algoritme is daarentegen een algoritme met het kortste pad uit alle paren dat dynamische programmering gebruikt om het kortste pad tussen alle paren knooppunten in de grafiek te berekenen.
Negatieve gewichtenHet algoritme van Dijkstra werkt niet met grafieken met negatieve randgewichten, omdat het ervan uitgaat dat alle randgewichten niet-negatief zijn.Het Floyd-Warshall-algoritme is daarentegen een algoritme met het kortste pad uit alle paren dat dynamische programmering gebruikt om het kortste pad tussen alle paren knooppunten in de grafiek te berekenen.

Dijkstra's algoritme versus A*-algoritme

Dijkstra's algoritme en Een* algoritme worden beide gebruikt om het kortste pad in een gewogen grafiek te vinden, maar ze hebben enkele belangrijke verschillen. Dit zijn de belangrijkste verschillen tussen het algoritme van Dijkstra en het A*-algoritme:

Functie: Een* algoritme
ZoektechniekGeoptimaliseerd voor het vinden van het kortste pad tussen een enkel bronknooppunt en alle andere knooppunten in een grafiek met niet-negatieve randgewichtenEen*-algoritme is een geïnformeerd zoekalgoritme dat een heuristische functie gebruikt om de zoekopdracht naar het doelknooppunt te leiden.
Heuristische functieHet algoritme van Dijkstra gebruikt geen enkele heuristische functie en houdt rekening met alle knooppunten in de grafiek.Een*-algoritme gebruikt een heuristische functie die de afstand schat van het huidige knooppunt tot het doelknooppunt. Deze heuristische functie is toelaatbaar, wat betekent dat deze nooit de werkelijke afstand tot het doelknooppunt overschat
TijdcomplexiteitHet algoritme van Dijkstra heeft een tijdscomplexiteit van O(V^2) voor een dichte grafiek en O(E log V) voor een dunne grafiek, waarbij V het aantal hoekpunten is en E het aantal randen in de grafiek.De tijdscomplexiteit van het A*-algoritme hangt af van de kwaliteit van de heuristische functie.
SollicitatieHet algoritme van Dijkstra wordt in veel toepassingen gebruikt, zoals routeringsalgoritmen, GPS-navigatiesystemen en netwerkanalyse. Een*-algoritme wordt vaak gebruikt bij problemen met het vinden van paden en het doorlopen van grafieken, zoals bij videogames, robotica en planningsalgoritmen.

Oefenproblemen met het algoritme van Dijkstra:

  1. Dijkstra’s kortste pad-algoritme | Hebzuchtige Algo-7
  2. Dijkstra's algoritme voor weergave van aangrenzende lijsten | Hebzuchtige Algo-8
  3. Dijkstra's algoritme - Prioritaire wachtrij en array-implementatie
  4. Dijkstra's kortste pad-algoritme met behulp van set in STL
  5. Dijkstra's kortste pad-algoritme met behulp van STL in C++
  6. Dijkstra's kortste pad-algoritme met behulp van prioriteit_wachtrij van STL
  7. Dijkstra's kortste pad-algoritme met behulp van matrix in C++
  8. Dijkstra's algoritme voor het kortste pad van één bron in een DAG
  9. Dijkstra's algoritme met behulp van Fibonacci Heap
  10. Dijkstra's kortste pad-algoritme voor gerichte grafiek met negatieve gewichten
  11. Paden afdrukken in het kortste padalgoritme van Dijkstra
  12. Dijkstra's kortste pad-algoritme met prioriteitswachtrij in Java