logo

So finden Sie mit dem Dijkstra-Algorithmus die kürzesten Pfade von der Quelle zu allen Eckpunkten

Finden Sie anhand eines gewichteten Diagramms und eines Quellscheitelpunkts im Diagramm das kürzeste Wege von der Quelle zu allen anderen Eckpunkten im angegebenen Diagramm.

Notiz: Der angegebene Graph enthält keine negative Kante.

Beispiele:



Eingang: src = 0, das Diagramm ist unten dargestellt.

1-(2)

Ausgabe: 0 4 12 19 21 11 9 8 14
Erläuterung: Der Abstand von 0 zu 1 = 4.
Der Mindestabstand von 0 bis 2 = 12. 0->1->2
Der Mindestabstand von 0 bis 3 = 19. 0->1->2->3
Der Mindestabstand von 0 bis 4 = 21. 0->7->6->5->4
Der Mindestabstand von 0 bis 5 = 11. 0->7->6->5
Der Mindestabstand von 0 bis 6 = 9. 0->7->6
Der Mindestabstand von 0 bis 7 = 8. 0->7
Der Mindestabstand von 0 bis 8 = 14. 0->1->2->8

Empfohlene Praxis zur Implementierung des Dijkstra-Algorithmus Probieren Sie es aus!

Dijkstras Algorithmus unter Verwendung Adjazenzmatrix :

Die Idee ist, eine zu generieren SPT (kürzester Pfadbaum) mit einer bestimmten Quelle als Wurzel. Pflegen Sie eine Adjazenzmatrix mit zwei Sätzen,

  • Ein Satz enthält Eckpunkte, die im Baum des kürzesten Pfads enthalten sind.
  • Der andere Satz enthält Scheitelpunkte, die noch nicht im Baum des kürzesten Pfads enthalten sind.

Suchen Sie bei jedem Schritt des Algorithmus einen Scheitelpunkt, der sich in der anderen Menge befindet (die Menge ist noch nicht enthalten) und einen Mindestabstand von der Quelle hat.

Algorithmus :

  • Erstellen Sie ein Set sptSet (Baumsatz des kürzesten Pfads), der die im Baum des kürzesten Pfads enthaltenen Scheitelpunkte verfolgt, d. h. deren Mindestabstand von der Quelle berechnet und finalisiert wird. Dieses Set ist zunächst leer.
  • Weisen Sie allen Scheitelpunkten im Eingabediagramm einen Abstandswert zu. Alle Distanzwerte initialisieren als UNENDLICH . Weisen Sie dem Quellscheitelpunkt den Abstandswert 0 zu, sodass dieser zuerst ausgewählt wird.
  • Während sptSet umfasst nicht alle Eckpunkte
    • Wählen Sie einen Scheitelpunkt In das steht da nicht drin sptSet und hat einen Mindestabstandswert.
    • Beziehen Sie uns mit ein sptSet .
    • Aktualisieren Sie dann den Abstandswert aller benachbarten Scheitelpunkte von In .
      • Um die Abstandswerte zu aktualisieren, durchlaufen Sie alle benachbarten Scheitelpunkte.
      • Für jeden angrenzenden Scheitelpunkt In, wenn die Summe der Distanzwerte von In (aus Quelle) und Gewicht der Kante u-v , ist kleiner als der Abstandswert von In , und aktualisieren Sie dann den Abstandswert von In .

Notiz: Wir verwenden ein boolesches Array sptSet[] um die Menge der darin enthaltenen Eckpunkte darzustellen SPT . Wenn ein Wert sptSet[v] wahr ist, dann ist Scheitelpunkt v enthalten SPT , sonst nicht. Array dist[] wird verwendet, um die kürzesten Abstandswerte aller Scheitelpunkte zu speichern.

Illustration des Dijkstra-Algorithmus :

Um den Dijkstra-Algorithmus zu verstehen, nehmen wir einen Graphen und finden den kürzesten Weg von der Quelle zu allen Knoten.

Betrachten Sie die folgende Grafik und Quelle = 0

1-(2)

Schritt 1:

  • Der Satz sptSet ist zunächst leer und die den Scheitelpunkten zugewiesenen Abstände sind {0, INF, INF, INF, INF, INF, INF, INF} wobei INF bedeutet unendlich.
  • Wählen Sie nun den Scheitelpunkt mit einem minimalen Abstandswert aus. Der Scheitelpunkt 0 wird ausgewählt, fügen Sie ihn ein sptSet . Also sptSet wird zu {0}. Nach Einbeziehung von 0 bis sptSet , aktualisieren Sie die Abstandswerte der angrenzenden Scheitelpunkte.
  • Benachbarte Eckpunkte von 0 sind 1 und 7. Die Abstandswerte von 1 und 7 werden als 4 und 8 aktualisiert.

Das folgende Unterdiagramm zeigt Scheitelpunkte und ihre Abstandswerte. Es werden nur die Scheitelpunkte mit endlichen Abstandswerten angezeigt. Die darin enthaltenen Eckpunkte SPT werden in angezeigt Grün Farbe.

6


Schritt 2:

Java-Switch int
  • Wählen Sie den Scheitelpunkt mit dem Mindestabstandswert aus, der noch nicht enthalten ist SPT (nicht in sptSET ). Der Scheitelpunkt 1 wird ausgewählt und hinzugefügt sptSet .
  • Also sptSet wird jetzt zu {0, 1}. Aktualisieren Sie die Abstandswerte benachbarter Scheitelpunkte von 1.
  • Der Abstandswert von Scheitelpunkt 2 wird 12 .
    4


Schritt 3:

  • Wählen Sie den Scheitelpunkt mit dem Mindestabstandswert aus, der noch nicht enthalten ist SPT (nicht in sptSET ). Scheitelpunkt 7 wird ausgewählt. Also sptSet wird jetzt {0, 1, 7}.
  • Aktualisieren Sie die Abstandswerte benachbarter Scheitelpunkte von 7. Der Abstandswert der Scheitelpunkte 6 und 8 wird endlich ( 15 und 9 jeweils).
    5


Schritt 4:

  • Wählen Sie den Scheitelpunkt mit dem Mindestabstandswert aus, der noch nicht enthalten ist SPT (nicht in sptSET ). Scheitelpunkt 6 wird ausgewählt. Also sptSet wird jetzt {0, 1, 7, 6} .
  • Aktualisieren Sie die Abstandswerte benachbarter Scheitelpunkte von 6. Die Abstandswerte von Scheitelpunkt 5 und 8 werden aktualisiert.
    3-(1)


Wir wiederholen die obigen Schritte bis sptSet beinhaltet alle Eckpunkte des angegebenen Diagramms. Schließlich erhalten wir das folgende S kürzester Pfadbaum (SPT).

2-(2)

Nachfolgend finden Sie die Umsetzung des oben genannten Ansatzes:

C++
// C++ program for Dijkstra's single source shortest path // algorithm. The program is for adjacency matrix // representation of the graph #include  using namespace std; #include  // Number of vertices in the graph #define V 9 // A utility function to find the vertex with minimum // distance value, from the set of vertices not yet included // in shortest path tree int minDistance(int dist[], bool sptSet[]) {  // Initialize min value  int min = INT_MAX, min_index;  for (int v = 0; v < V; v++)  if (sptSet[v] == false && dist[v] <= min)  min = dist[v], min_index = v;  return min_index; } // A utility function to print the constructed distance // array void printSolution(int dist[]) {  cout << 'Vertex 	 Distance from Source' << endl;  for (int i = 0; i < V; i++)  cout << i << ' 				' << dist[i] << endl; } // Function that implements Dijkstra's single source // shortest path algorithm for a graph represented using // adjacency matrix representation void dijkstra(int graph[V][V], int src) {  int dist[V]; // The output array. dist[i] will hold the  // shortest  // distance from src to i  bool sptSet[V]; // sptSet[i] will be true if vertex i is  // included in shortest  // path tree or shortest distance from src to i is  // finalized  // Initialize all distances as INFINITE and stpSet[] as  // false  for (int i = 0; i < V; i++)  dist[i] = INT_MAX, sptSet[i] = false;  // Distance of source vertex from itself is always 0  dist[src] = 0;  // Find shortest path for all vertices  for (int count = 0; count < V - 1; count++) {  // Pick the minimum distance vertex from the set of  // vertices not yet processed. u is always equal to  // src in the first iteration.  int u = minDistance(dist, sptSet);  // Mark the picked vertex as processed  sptSet[u] = true;  // Update dist value of the adjacent vertices of the  // picked vertex.  for (int v = 0; v < V; v++)  // Update dist[v] only if is not in sptSet,  // there is an edge from u to v, and total  // weight of path from src to v through u is  // smaller than current value of dist[v]  if (!sptSet[v] && graph[u][v]  && dist[u] != INT_MAX  && dist[u] + graph[u][v] < dist[v])  dist[v] = dist[u] + graph[u][v];  }  // print the constructed distance array  printSolution(dist); } // driver's code int main() {  /* Let us create the example graph discussed above */  int graph[V][V] = { { 0, 4, 0, 0, 0, 0, 0, 8, 0 },  { 4, 0, 8, 0, 0, 0, 0, 11, 0 },  { 0, 8, 0, 7, 0, 4, 0, 0, 2 },  { 0, 0, 7, 0, 9, 14, 0, 0, 0 },  { 0, 0, 0, 9, 0, 10, 0, 0, 0 },  { 0, 0, 4, 14, 10, 0, 2, 0, 0 },  { 0, 0, 0, 0, 0, 2, 0, 1, 6 },  { 8, 11, 0, 0, 0, 0, 1, 0, 7 },  { 0, 0, 2, 0, 0, 0, 6, 7, 0 } };  // Function call  dijkstra(graph, 0);  return 0; } // This code is contributed by shivanisinghss2110>
C
// C program for Dijkstra's single source shortest path // algorithm. The program is for adjacency matrix // representation of the graph #include  #include  #include  // Number of vertices in the graph #define V 9 // A utility function to find the vertex with minimum // distance value, from the set of vertices not yet included // in shortest path tree int minDistance(int dist[], bool sptSet[]) {  // Initialize min value  int min = INT_MAX, min_index;  for (int v = 0; v < V; v++)  if (sptSet[v] == false && dist[v] <= min)  min = dist[v], min_index = v;  return min_index; } // A utility function to print the constructed distance // array void printSolution(int dist[]) {  printf('Vertex 		 Distance from Source
');  for (int i = 0; i < V; i++)  printf('%d 				 %d
', i, dist[i]); } // Function that implements Dijkstra's single source // shortest path algorithm for a graph represented using // adjacency matrix representation void dijkstra(int graph[V][V], int src) {  int dist[V]; // The output array. dist[i] will hold the  // shortest  // distance from src to i  bool sptSet[V]; // sptSet[i] will be true if vertex i is  // included in shortest  // path tree or shortest distance from src to i is  // finalized  // Initialize all distances as INFINITE and stpSet[] as  // false  for (int i = 0; i < V; i++)  dist[i] = INT_MAX, sptSet[i] = false;  // Distance of source vertex from itself is always 0  dist[src] = 0;  // Find shortest path for all vertices  for (int count = 0; count < V - 1; count++) {  // Pick the minimum distance vertex from the set of  // vertices not yet processed. u is always equal to  // src in the first iteration.  int u = minDistance(dist, sptSet);  // Mark the picked vertex as processed  sptSet[u] = true;  // Update dist value of the adjacent vertices of the  // picked vertex.  for (int v = 0; v < V; v++)  // Update dist[v] only if is not in sptSet,  // there is an edge from u to v, and total  // weight of path from src to v through u is  // smaller than current value of dist[v]  if (!sptSet[v] && graph[u][v]  && dist[u] != INT_MAX  && dist[u] + graph[u][v] < dist[v])  dist[v] = dist[u] + graph[u][v];  }  // print the constructed distance array  printSolution(dist); } // driver's code int main() {  /* Let us create the example graph discussed above */  int graph[V][V] = { { 0, 4, 0, 0, 0, 0, 0, 8, 0 },  { 4, 0, 8, 0, 0, 0, 0, 11, 0 },  { 0, 8, 0, 7, 0, 4, 0, 0, 2 },  { 0, 0, 7, 0, 9, 14, 0, 0, 0 },  { 0, 0, 0, 9, 0, 10, 0, 0, 0 },  { 0, 0, 4, 14, 10, 0, 2, 0, 0 },  { 0, 0, 0, 0, 0, 2, 0, 1, 6 },  { 8, 11, 0, 0, 0, 0, 1, 0, 7 },  { 0, 0, 2, 0, 0, 0, 6, 7, 0 } };  // Function call  dijkstra(graph, 0);  return 0; }>
Java
// A Java program for Dijkstra's single source shortest path // algorithm. The program is for adjacency matrix // representation of the graph import java.io.*; import java.lang.*; import java.util.*; class ShortestPath {  // A utility function to find the vertex with minimum  // distance value, from the set of vertices not yet  // included in shortest path tree  static final int V = 9;  int minDistance(int dist[], Boolean sptSet[])  {  // Initialize min value  int min = Integer.MAX_VALUE, min_index = -1;  for (int v = 0; v < V; v++)  if (sptSet[v] == false && dist[v] <= min) {  min = dist[v];  min_index = v;  }  return min_index;  }  // A utility function to print the constructed distance  // array  void printSolution(int dist[])  {  System.out.println(  'Vertex 		 Distance from Source');  for (int i = 0; i < V; i++)  System.out.println(i + ' 		 ' + dist[i]);  }  // Function that implements Dijkstra's single source  // shortest path algorithm for a graph represented using  // adjacency matrix representation  void dijkstra(int graph[][], int src)  {  int dist[] = new int[V]; // The output array.  // dist[i] will hold  // the shortest distance from src to i  // sptSet[i] will true if vertex i is included in  // shortest path tree or shortest distance from src  // to i is finalized  Boolean sptSet[] = new Boolean[V];  // Initialize all distances as INFINITE and stpSet[]  // as false  for (int i = 0; i < V; i++) {  dist[i] = Integer.MAX_VALUE;  sptSet[i] = false;  }  // Distance of source vertex from itself is always 0  dist[src] = 0;  // Find shortest path for all vertices  for (int count = 0; count < V - 1; count++) {  // Pick the minimum distance vertex from the set  // of vertices not yet processed. u is always  // equal to src in first iteration.  int u = minDistance(dist, sptSet);  // Mark the picked vertex as processed  sptSet[u] = true;  // Update dist value of the adjacent vertices of  // the picked vertex.  for (int v = 0; v < V; v++)  // Update dist[v] only if is not in sptSet,  // there is an edge from u to v, and total  // weight of path from src to v through u is  // smaller than current value of dist[v]  if (!sptSet[v] && graph[u][v] != 0  && dist[u] != Integer.MAX_VALUE  && dist[u] + graph[u][v] < dist[v])  dist[v] = dist[u] + graph[u][v];  }  // print the constructed distance array  printSolution(dist);  }  // Driver's code  public static void main(String[] args)  {  /* Let us create the example graph discussed above  */  int graph[][]  = new int[][] { { 0, 4, 0, 0, 0, 0, 0, 8, 0 },  { 4, 0, 8, 0, 0, 0, 0, 11, 0 },  { 0, 8, 0, 7, 0, 4, 0, 0, 2 },  { 0, 0, 7, 0, 9, 14, 0, 0, 0 },  { 0, 0, 0, 9, 0, 10, 0, 0, 0 },  { 0, 0, 4, 14, 10, 0, 2, 0, 0 },  { 0, 0, 0, 0, 0, 2, 0, 1, 6 },  { 8, 11, 0, 0, 0, 0, 1, 0, 7 },  { 0, 0, 2, 0, 0, 0, 6, 7, 0 } };  ShortestPath t = new ShortestPath();  // Function call  t.dijkstra(graph, 0);  } } // This code is contributed by Aakash Hasija>
Python
# Python program for Dijkstra's single # source shortest path algorithm. The program is # for adjacency matrix representation of the graph # Library for INT_MAX import sys class Graph(): def __init__(self, vertices): self.V = vertices self.graph = [[0 for column in range(vertices)] for row in range(vertices)] def printSolution(self, dist): print('Vertex 	Distance from Source') for node in range(self.V): print(node, '	', dist[node]) # A utility function to find the vertex with # minimum distance value, from the set of vertices # not yet included in shortest path tree def minDistance(self, dist, sptSet): # Initialize minimum distance for next node min = sys.maxsize # Search not nearest vertex not in the # shortest path tree for u in range(self.V): if dist[u] < min and sptSet[u] == False: min = dist[u] min_index = u return min_index # Function that implements Dijkstra's single source # shortest path algorithm for a graph represented # using adjacency matrix representation def dijkstra(self, src): dist = [sys.maxsize] * self.V dist[src] = 0 sptSet = [False] * self.V for cout in range(self.V): # Pick the minimum distance vertex from # the set of vertices not yet processed. # x is always equal to src in first iteration x = self.minDistance(dist, sptSet) # Put the minimum distance vertex in the # shortest path tree sptSet[x] = True # Update dist value of the adjacent vertices # of the picked vertex only if the current # distance is greater than new distance and # the vertex in not in the shortest path tree for y in range(self.V): if self.graph[x][y]>0 und sptSet[y] == False und  dist[y]> dist[x] + self.graph[x][y]: dist[y] = dist[x] + self.graph[x][y] self.printSolution(dist) # Treibercode if __name__ == '__main__': g = Graph(9) g.graph = [[0, 4, 0, 0, 0, 0, 0, 8, 0], [4, 0, 8, 0, 0, 0, 0, 11, 0], [0, 8, 0, 7, 0, 4, 0, 0, 2], [0, 0, 7, 0, 9, 14, 0, 0, 0], [0, 0, 0, 9, 0, 10, 0, 0, 0], [0, 0, 4, 14, 10, 0, 2, 0, 0], [0, 0, 0, 0, 0, 2, 0, 1, 6], [8, 11, 0, 0, 0, 0, 1, 0, 7], [0, 0, 2, 0, 0, 0, 6, 7, 0] ] g.dijkstra(0) # Dieser Code wurde von Divyanshu Mehta beigesteuert und von Pranav Singh Sambyal aktualisiert>
C#
// C# program for Dijkstra's single // source shortest path algorithm. // The program is for adjacency matrix // representation of the graph using System; class GFG {  // A utility function to find the  // vertex with minimum distance  // value, from the set of vertices  // not yet included in shortest  // path tree  static int V = 9;  int minDistance(int[] dist, bool[] sptSet)  {  // Initialize min value  int min = int.MaxValue, min_index = -1;  for (int v = 0; v < V; v++)  if (sptSet[v] == false && dist[v] <= min) {  min = dist[v];  min_index = v;  }  return min_index;  }  // A utility function to print  // the constructed distance array  void printSolution(int[] dist)  {  Console.Write('Vertex 		 Distance '  + 'from Source
');  for (int i = 0; i < V; i++)  Console.Write(i + ' 		 ' + dist[i] + '
');  }  // Function that implements Dijkstra's  // single source shortest path algorithm  // for a graph represented using adjacency  // matrix representation  void dijkstra(int[, ] graph, int src)  {  int[] dist  = new int[V]; // The output array. dist[i]  // will hold the shortest  // distance from src to i  // sptSet[i] will true if vertex  // i is included in shortest path  // tree or shortest distance from  // src to i is finalized  bool[] sptSet = new bool[V];  // Initialize all distances as  // INFINITE and stpSet[] as false  for (int i = 0; i < V; i++) {  dist[i] = int.MaxValue;  sptSet[i] = false;  }  // Distance of source vertex  // from itself is always 0  dist[src] = 0;  // Find shortest path for all vertices  for (int count = 0; count < V - 1; count++) {  // Pick the minimum distance vertex  // from the set of vertices not yet  // processed. u is always equal to  // src in first iteration.  int u = minDistance(dist, sptSet);  // Mark the picked vertex as processed  sptSet[u] = true;  // Update dist value of the adjacent  // vertices of the picked vertex.  for (int v = 0; v < V; v++)  // Update dist[v] only if is not in  // sptSet, there is an edge from u  // to v, and total weight of path  // from src to v through u is smaller  // than current value of dist[v]  if (!sptSet[v] && graph[u, v] != 0  && dist[u] != int.MaxValue  && dist[u] + graph[u, v] < dist[v])  dist[v] = dist[u] + graph[u, v];  }  // print the constructed distance array  printSolution(dist);  }  // Driver's Code  public static void Main()  {  /* Let us create the example graph discussed above */  int[, ] graph  = new int[, ] { { 0, 4, 0, 0, 0, 0, 0, 8, 0 },  { 4, 0, 8, 0, 0, 0, 0, 11, 0 },  { 0, 8, 0, 7, 0, 4, 0, 0, 2 },  { 0, 0, 7, 0, 9, 14, 0, 0, 0 },  { 0, 0, 0, 9, 0, 10, 0, 0, 0 },  { 0, 0, 4, 14, 10, 0, 2, 0, 0 },  { 0, 0, 0, 0, 0, 2, 0, 1, 6 },  { 8, 11, 0, 0, 0, 0, 1, 0, 7 },  { 0, 0, 2, 0, 0, 0, 6, 7, 0 } };  GFG t = new GFG();  // Function call  t.dijkstra(graph, 0);  } } // This code is contributed by ChitraNayal>
Javascript
// A Javascript program for Dijkstra's single  // source shortest path algorithm.  // The program is for adjacency matrix  // representation of the graph  let V = 9; // A utility function to find the  // vertex with minimum distance  // value, from the set of vertices  // not yet included in shortest  // path tree  function minDistance(dist,sptSet) {    // Initialize min value   let min = Number.MAX_VALUE;  let min_index = -1;    for(let v = 0; v < V; v++)  {  if (sptSet[v] == false && dist[v] <= min)   {  min = dist[v];  min_index = v;  }  }  return min_index; } // A utility function to print  // the constructed distance array  function printSolution(dist) {  console.log('Vertex 		 Distance from Source ');  for(let i = 0; i < V; i++)  {  console.log(i + ' 		 ' +   dist[i] + ' ');  } } // Function that implements Dijkstra's  // single source shortest path algorithm  // for a graph represented using adjacency  // matrix representation  function dijkstra(graph, src) {  let dist = new Array(V);  let sptSet = new Array(V);    // Initialize all distances as   // INFINITE and stpSet[] as false   for(let i = 0; i < V; i++)  {  dist[i] = Number.MAX_VALUE;  sptSet[i] = false;  }    // Distance of source vertex   // from itself is always 0   dist[src] = 0;    // Find shortest path for all vertices   for(let count = 0; count < V - 1; count++)  {    // Pick the minimum distance vertex   // from the set of vertices not yet   // processed. u is always equal to   // src in first iteration.   let u = minDistance(dist, sptSet);    // Mark the picked vertex as processed   sptSet[u] = true;    // Update dist value of the adjacent   // vertices of the picked vertex.   for(let v = 0; v < V; v++)  {    // Update dist[v] only if is not in   // sptSet, there is an edge from u   // to v, and total weight of path   // from src to v through u is smaller   // than current value of dist[v]   if (!sptSet[v] && graph[u][v] != 0 &&   dist[u] != Number.MAX_VALUE &&  dist[u] + graph[u][v] < dist[v])  {  dist[v] = dist[u] + graph[u][v];  }  }  }    // Print the constructed distance array  printSolution(dist); } // Driver code let graph = [ [ 0, 4, 0, 0, 0, 0, 0, 8, 0 ],  [ 4, 0, 8, 0, 0, 0, 0, 11, 0 ],  [ 0, 8, 0, 7, 0, 4, 0, 0, 2 ],  [ 0, 0, 7, 0, 9, 14, 0, 0, 0],  [ 0, 0, 0, 9, 0, 10, 0, 0, 0 ],  [ 0, 0, 4, 14, 10, 0, 2, 0, 0],  [ 0, 0, 0, 0, 0, 2, 0, 1, 6 ],  [ 8, 11, 0, 0, 0, 0, 1, 0, 7 ],  [ 0, 0, 2, 0, 0, 0, 6, 7, 0 ] ] dijkstra(graph, 0); // This code is contributed by rag2127>

Ausgabe
Vertex Distance from Source 0 0 1 4 2 12 3 19 4 21 5 11 6 9 7 8 8 14>

Zeitkomplexität: O(V2)
Hilfsraum: O(V)

Anmerkungen:

  • Der Code berechnet die kürzeste Entfernung, berechnet jedoch nicht die Pfadinformationen. Erstellen Sie ein übergeordnetes Array, aktualisieren Sie das übergeordnete Array, wenn die Entfernung aktualisiert wird, und zeigen Sie damit den kürzesten Pfad von der Quelle zu verschiedenen Scheitelpunkten an.
  • Die zeitliche Komplexität der Umsetzung beträgt O(V 2 ) . Wenn die Eingabe Das Diagramm wird mithilfe einer Adjazenzliste dargestellt , kann es mit Hilfe eines binären Heaps auf O(E * log V) reduziert werden. Bitte sehen Dijkstras Algorithmus zur Darstellung von Adjazenzlisten für mehr Details.
  • Der Dijkstra-Algorithmus funktioniert nicht für Diagramme mit negativen Gewichtszyklen.

Warum versagen Dijkstras Algorithmen bei Diagrammen mit negativen Kanten?

Das Problem mit negativen Gewichten ergibt sich aus der Tatsache, dass der Dijkstra-Algorithmus davon ausgeht, dass, sobald ein Knoten zur Menge der besuchten Knoten hinzugefügt wird, seine Entfernung endgültig ist und sich nicht ändert. Bei negativen Gewichten kann diese Annahme jedoch zu falschen Ergebnissen führen.

Wie viele Unzen sind 10 Milliliter?

Betrachten Sie als Beispiel die folgende Grafik:

Ausfall von Dijkstra bei negativen Flanken

Im obigen Diagramm ist A der Quellknoten zwischen den Kanten A Zu B Und A Zu C , A Zu B ist das kleinere Gewicht und Dijkstra weist den kürzesten Abstand zu B wie 2, aber wegen der Existenz einer negativen Flanke von C Zu B , reduziert sich die tatsächliche kürzeste Entfernung auf 1, was Dijkstra nicht erkennt.

Notiz: Wir gebrauchen Bellman Fords Kürzester-Weg-Algorithmus für den Fall, dass wir negative Kanten im Diagramm haben.

Dijkstras Algorithmus unter Verwendung Adjazenzliste in O(E logV):

Für den Dijkstra-Algorithmus wird immer die Verwendung empfohlen Immer wenn der Abstand eines Scheitelpunkts verringert wird, fügen wir eine weitere Instanz eines Scheitelpunkts in der Prioritätswarteschlange hinzu. Selbst wenn es mehrere Instanzen gibt, berücksichtigen wir nur die Instanz mit dem Mindestabstand und ignorieren andere Instanzen.

  • Die zeitliche Komplexität bleibt bestehen O(E * LogV) da es höchstens O(E) Scheitelpunkte in der Prioritätswarteschlange gibt und O(logE) dasselbe ist wie O(logV)
  • Nachfolgend finden Sie die Umsetzung des oben genannten Ansatzes:

    C++
    // C++ Program to find Dijkstra's shortest path using // priority_queue in STL #include  using namespace std; #define INF 0x3f3f3f3f // iPair ==>Integer-Paar Typedef-Paar iPair; // Diese Klasse repräsentiert einen gerichteten Graphen mit // Adjazenzlistendarstellung class Graph { int V; // Anzahl der Scheitelpunkte // In einem gewichteten Diagramm müssen wir Scheitelpunkte // und Gewichtspaare für jede Kantenliste speichern>* adj; public: Graph(int V); // Konstruktor // Funktion zum Hinzufügen einer Kante zum Diagramm void addEdge(int u, int v, int w);  // druckt den kürzesten Pfad von s void shortestPath(int s); }; // Reserviert Speicher für Adjazenzliste Graph::Graph(int V) { this->V = V;  adj = neue Liste [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)); } // Druckt die kürzesten Pfade von src zu allen anderen Scheitelpunkten. void Graph::shortestPath(int src) { // Erstellen Sie eine Prioritätswarteschlange, um Scheitelpunkte zu speichern, die // vorverarbeitet werden. Das ist eine seltsame Syntax in C++.  // Einzelheiten zu dieser Syntax finden Sie unter dem folgenden Link // https://www.techcodeview.com Priority_queue , größer > pq;  // Erstelle einen Vektor für Entfernungen und initialisiere alle // Entfernungen als unendlichen (INF) Vektor dist(V, INF);  // Quelle selbst in Prioritätswarteschlange einfügen und // ihren Abstand als 0 initialisieren. pq.push(make_pair(0, src));  dist[src] = 0;  /* Schleife, bis die Prioritätswarteschlange leer wird (oder nicht alle Abstände festgelegt sind) */ while (!pq.empty()) { // Der erste Scheitelpunkt im Paar ist der Mindestabstand // Scheitelpunkt, extrahiere ihn aus der Prioritätswarteschlange.  // Die Scheitelpunktbeschriftung wird im zweiten Teil des Paares gespeichert (dies // muss auf diese Weise erfolgen, um den // sortierten Abstand der Scheitelpunkte beizubehalten (der Abstand muss das erste Element // im Paar sein) int u = pq.top().second; pq.pop(); // 'i' wird verwendet, um alle benachbarten Scheitelpunkte einer // Scheitelpunktliste abzurufen>::iterator i;  for (i = adj[u].begin(); i != adj[u].end(); ++i) { // Scheitelpunktbezeichnung und Gewicht des aktuellen // Nachbars von u abrufen.  int v = (*i).first;  int Weight = (*i).second;  // Wenn es einen kurzen Pfad zu v durch u gibt.  if (dist[v]> dist[u] + Gewicht) { // Abstand von v aktualisieren dist[v] = dist[u] + Gewicht;  pq.push(make_pair(dist[v], v));  } } } // Kürzeste in dist[] gespeicherte Abstände drucken printf('Vertex Distance from Source
    ');  für (int i = 0; i< V; ++i)  printf('%d 		 %d
    ', i, dist[i]); } // Driver's code int main() {  // create the graph given in above figure  int V = 9;  Graph g(V);  // making above shown graph  g.addEdge(0, 1, 4);  g.addEdge(0, 7, 8);  g.addEdge(1, 2, 8);  g.addEdge(1, 7, 11);  g.addEdge(2, 3, 7);  g.addEdge(2, 8, 2);  g.addEdge(2, 5, 4);  g.addEdge(3, 4, 9);  g.addEdge(3, 5, 14);  g.addEdge(4, 5, 10);  g.addEdge(5, 6, 2);  g.addEdge(6, 7, 1);  g.addEdge(6, 8, 6);  g.addEdge(7, 8, 7);  // Function call  g.shortestPath(0);  return 0; }>
    Java
    import java.util.*; class Graph {  private int V;  private List> adj;  Graph(int V) { this.V = V;  adj = new ArrayList();  für (int i = 0; i< V; i++) {  adj.add(new ArrayList());  }  }  void addEdge(int u, int v, int w) {  adj.get(u).add(new iPair(v, w));  adj.get(v).add(new iPair(u, w));  }  void shortestPath(int src) {  PriorityQueue pq = new PriorityQueue(V, Comparator.comparingInt(o -> o.second));  int[] dist = new int[V];  Arrays.fill(dist, Integer.MAX_VALUE);  pq.add(new iPair(0, src));  dist[src] = 0;  while (!pq.isEmpty()) { int u = pq.poll().second;  for (iPair v : adj.get(u)) { if (dist[v.first]> dist[u] + v.second) { dist[v.first] = dist[u] + v.second;  pq.add(new iPair(dist[v.first], v.first));  } } } System.out.println('Vertex Distance from Source');  für (int i = 0; i< V; i++) {  System.out.println(i + '		' + dist[i]);  }  }  static class iPair {  int first, second;  iPair(int first, int second) {  this.first = first;  this.second = second;  }  } } public class Main {  public static void main(String[] args) {  int V = 9;  Graph g = new Graph(V);  g.addEdge(0, 1, 4);  g.addEdge(0, 7, 8);  g.addEdge(1, 2, 8);  g.addEdge(1, 7, 11);  g.addEdge(2, 3, 7);  g.addEdge(2, 8, 2);  g.addEdge(2, 5, 4);  g.addEdge(3, 4, 9);  g.addEdge(3, 5, 14);  g.addEdge(4, 5, 10);  g.addEdge(5, 6, 2);  g.addEdge(6, 7, 1);  g.addEdge(6, 8, 6);  g.addEdge(7, 8, 7);  g.shortestPath(0);  } }>
    Python
    import heapq # iPair ==>Ganzzahliges Paar iPair = tuple # Diese Klasse stellt einen gerichteten Graphen dar, der # Adjazenzlisten-Darstellungsklasse verwendet. Graph: def __init__(self, V: int): # Konstruktor self.V = V self.adj = [[] for _ in range(V )] def addEdge(self, u: int, v: int, w: int): self.adj[u].append((v, w)) self.adj[v].append((u, w)) # Druckt die kürzesten Pfade von src zu allen anderen Vertices def shortestPath(self, src: int): # Erstellen Sie eine Prioritätswarteschlange, um Vertices zu speichern, die # vorverarbeitet werden pq = [] heapq.heappush(pq, (0, src)) # Erstellen Sie einen Vektor für Abstände und initialisieren Sie alle # Abstände als unendlich (INF) dist = [float('inf')] * self.V dist[src] = 0 while pq: # Der erste Scheitelpunkt im Paar ist der Mindestabstand # Scheitelpunkt, extrahieren Sie ihn aus der Prioritätswarteschlange. # Scheitelpunktbezeichnung wird in Sekunde von Paar d, u = heapq.heappop(pq) gespeichert # 'i' wird verwendet, um alle benachbarten Scheitelpunkte eines # Scheitelpunkts für v zu erhalten, Gewicht in self.adj[u]: # If Es gibt einen kurzen Weg zu v durch u. if dist[v]> dist[u] + Gewicht: # Aktualisierung der Entfernung von v dist[v] = dist[u] + Gewicht heapq.heappush(pq, (dist[v], v)) # Kürzeste gespeicherte Entfernungen drucken dist[] for i in range(self.V): print(f'{i} 		 {dist[i]}') # Treibercode, wenn __name__ == '__main__': # Erstellen Sie den in der obigen Abbildung angegebenen Graphen V = 9 g = Graph(V) # Erstellen Sie den oben gezeigten Graphen g.addEdge(0, 1, 4) g.addEdge(0, 7, 8) g.addEdge(1, 2, 8) g.addEdge(1, 7, 11) g.addEdge(2, 3, 7) g.addEdge(2, 8, 2) g.addEdge(2, 5, 4) g.addEdge(3, 4, 9) g.addEdge(3, 5, 14) g.addEdge(4, 5, 10) g.addEdge(5, 6, 2) g.addEdge(6, 7, 1) g.addEdge(6, 8, 6) g.addEdge(7, 8, 7) g.shortestPath(0)>
    C#
    using System; using System.Collections.Generic; // This class represents a directed graph using // adjacency list representation public class Graph {  private const int INF = 2147483647;  private int V;  private List [] adj;  public Graph(int V) { // Anzahl der Eckpunkte this.V = V;  // In einem gewichteten Diagramm müssen wir Scheitelpunkte // und Gewichtspaare für jede Kante speichern this.adj = new List [V];  für (int i = 0; i< V; i++)  {  this.adj[i] = new List ();  } } public void AddEdge(int u, int v, int w) { this.adj[u].Add(new int[] { v, w });  this.adj[v].Add(new int[] { u, w });  } // Druckt die kürzesten Pfade von src zu allen anderen Scheitelpunkten. public void ShortestPath(int src) { // Erstellen Sie eine Prioritätswarteschlange, um Scheitelpunkte zu speichern, die // vorverarbeitet werden.  SortedSet pq = neues SortedSet (neuer DistanceComparer());  // Erstelle ein Array für Abstände und initialisiere alle // Abstände als unendlich (INF) int[] dist = new int[V];  für (int i = 0; i< V; i++)  {  dist[i] = INF;  }  // Insert source itself in priority queue and initialize  // its distance as 0.  pq.Add(new int[] { 0, src });  dist[src] = 0;  /* Looping till priority queue becomes empty (or all  distances are not finalized) */  while (pq.Count>0) { // Der erste Scheitelpunkt im Paar ist der Mindestabstand // Scheitelpunkt, extrahiere ihn aus der Prioritätswarteschlange.  // Scheitelpunktbeschriftung wird in der Sekunde des Paares gespeichert (dies // muss auf diese Weise erfolgen, damit die Scheitelpunkte // nach Abstand sortiert bleiben) int[] minDistVertex = pq.Min;  pq.Remove(minDistVertex);  int u = minDistVertex[1];  // 'i' wird verwendet, um alle benachbarten Scheitelpunkte eines // Scheitelpunkts abzurufen foreach (int[] adjVertex in this.adj[u]) { // Scheitelpunktbezeichnung und Gewicht des aktuellen // Nachbars von u abrufen.  int v = adjVertex[0];  int Weight = adjVertex[1];  // Wenn es einen kürzeren Weg zu v durch u gibt.  if (dist[v]> dist[u] + Gewicht) { // Abstand von v aktualisieren dist[v] = dist[u] + Gewicht;  pq.Add(new int[] { dist[v], v });  } } } // Kürzeste in dist[] gespeicherte Abstände drucken Console.WriteLine('Vertex Distance from Source');  für (int i = 0; i< V; ++i)  Console.WriteLine(i + '	' + dist[i]);  }  private class DistanceComparer : IComparer { public int Compare(int[] x, int[] y) { if (x[0] == y[0]) { return x[1] - y[1];  } return x[0] - y[0];  } } } public class Program { // Treibercode public static void Main() { // das in der obigen Abbildung angegebene Diagramm erstellen int V = 9;  Graph g = neuer Graph(V);  // oben gezeigtes Diagramm erstellen g.AddEdge(0, 1, 4);  g.AddEdge(0, 7, 8);  g.AddEdge(1, 2, 8);  g.AddEdge(1, 7, 11);  g.AddEdge(2, 3, 7);  g.AddEdge(2, 8, 2);  g.AddEdge(2, 5, 4);  g.AddEdge(3, 4, 9);  g.AddEdge(3, 5, 14);  g.AddEdge(4, 5, 10);  g.AddEdge(5, 6, 2);  g.AddEdge(6, 7, 1);  g.AddEdge(6, 8, 6);  g.AddEdge(7, 8, 7);  g.ShortestPath(0);  } } // Dieser Code wurde von bhardwajji beigesteuert>
    Javascript
    // javascript Program to find Dijkstra's shortest path using // priority_queue in STL const INF = 2147483647; // This class represents a directed graph using // adjacency list representation class Graph {    constructor(V){    // No. of vertices  this.V = V;    // In a weighted graph, we need to store vertex  // and weight pair for every edge  this.adj = new Array(V);  for(let i = 0; i < V; i++){  this.adj[i] = new Array();  }  }  addEdge(u, v, w)  {  this.adj[u].push([v, w]);  this.adj[v].push([u, w]);  }  // Prints shortest paths from src to all other vertices  shortestPath(src)  {  // Create a priority queue to store vertices that  // are being preprocessed. This is weird syntax in C++.  // Refer below link for details of this syntax  // https://www.techcodeview.com  let pq = [];  // Create a vector for distances and initialize all  // distances as infinite (INF)  let dist = new Array(V).fill(INF);  // Insert source itself in priority queue and initialize  // its distance as 0.  pq.push([0, src]);  dist[src] = 0;  /* Looping till priority queue becomes empty (or all  distances are not finalized) */  while (pq.length>0) { // Der erste Scheitelpunkt im Paar ist der Mindestabstand // Scheitelpunkt, extrahiere ihn aus der Prioritätswarteschlange.  // Scheitelpunktbeschriftung wird im zweiten Teil des Paares gespeichert (dies // muss auf diese Weise erfolgen, um den // sortierten Abstand der Scheitelpunkte beizubehalten (der Abstand muss das erste Element // im Paar sein) let u = pq[0][1]; pq.shift(); // 'i' wird verwendet, um alle benachbarten Scheitelpunkte eines // Scheitelpunkts zu erhalten for(let i = 0; i< this.adj[u].length; i++){    // Get vertex label and weight of current  // adjacent of u.  let v = this.adj[u][i][0];  let weight = this.adj[u][i][1];  // If there is shorted path to v through u.  if (dist[v]>dist[u] + Gewicht) { // Abstand von v aktualisieren dist[v] = dist[u] + Gewicht;  pq.push([dist[v], v]);  pq.sort((a, b) =>{ if(a[0] == b[0]) return a[1] - b[1]; return a[0] - b[0]; });  } } } // Kürzeste in dist[] gespeicherte Abstände ausgeben console.log('Vertex Distance from Source');  für (sei i = 0; i< V; ++i)  console.log(i, ' ', dist[i]);  } } // Driver's code // create the graph given in above figure let V = 9; let g = new Graph(V); // making above shown graph g.addEdge(0, 1, 4); g.addEdge(0, 7, 8); g.addEdge(1, 2, 8); g.addEdge(1, 7, 11); g.addEdge(2, 3, 7); g.addEdge(2, 8, 2); g.addEdge(2, 5, 4); g.addEdge(3, 4, 9); g.addEdge(3, 5, 14); g.addEdge(4, 5, 10); g.addEdge(5, 6, 2); g.addEdge(6, 7, 1); g.addEdge(6, 8, 6); g.addEdge(7, 8, 7); // Function call g.shortestPath(0); // The code is contributed by Nidhi goel.>

    Ausgabe
    Vertex Distance from Source 0 0 1 4 2 12 3 19 4 21 5 11 6 9 7 8 8 14>

    Zeitkomplexität: O(E * logV), wobei E die Anzahl der Kanten und V die Anzahl der Eckpunkte ist.
    Hilfsraum: O(V)

    Anwendungen des Dijkstra-Algorithmus:

    • Google Maps verwendet den Dijkstra-Algorithmus, um die kürzeste Entfernung zwischen Quelle und Ziel anzuzeigen.
    • In Computervernetzung Der Dijkstra-Algorithmus bildet die Grundlage für verschiedene Routing-Protokolle wie OSPF (Open Shortest Path First) und IS-IS (Intermediate System to Intermediate System).
    • Transport- und Verkehrsmanagementsysteme nutzen den Dijkstra-Algorithmus, um den Verkehrsfluss zu optimieren, Staus zu minimieren und die effizientesten Routen für Fahrzeuge zu planen.
    • Fluggesellschaften nutzen den Dijkstra-Algorithmus, um Flugrouten zu planen, die den Treibstoffverbrauch minimieren und die Reisezeit verkürzen.
    • Der Algorithmus von Dijkstra wird in der elektronischen Designautomatisierung zum Routing von Verbindungen auf integrierten Schaltkreisen und VLSI-Chips (Very-Large-Scale-Integration) eingesetzt.

    Eine ausführlichere Erklärung finden Sie in diesem Artikel Dijkstras Shortest-Path-Algorithmus unter Verwendung der Priority_Queue von STL .