logo

Jak najít nejkratší cesty od zdroje ke všem vrcholům pomocí Dijkstrova algoritmu

Vzhledem k váženému grafu a zdrojovému vrcholu v grafu najděte nejkratší cesty od zdroje ke všem ostatním vrcholům v daném grafu.

Poznámka: Daný graf neobsahuje žádnou zápornou hranu.

Příklady:



řetězec java indexof

Vstup: src = 0, graf je uveden níže.

1-(2)

Výstup: 0 4 12 19 21 11 9 8 14
Vysvětlení: Vzdálenost od 0 do 1 = 4.
Minimální vzdálenost od 0 do 2 = 12. 0->1->2
Minimální vzdálenost od 0 do 3 = 19. 0->1->2->3
Minimální vzdálenost od 0 do 4 = 21. 0->7->6->5->4
Minimální vzdálenost od 0 do 5 = 11. 0->7->6->5
Minimální vzdálenost od 0 do 6 = 9. 0->7->6
Minimální vzdálenost od 0 do 7 = 8. 0->7
Minimální vzdálenost od 0 do 8 = 14. 0->1->2->8

Doporučený postup implementace algoritmu Dijkstra Vyzkoušejte to!

Použití Dijkstrova algoritmu Matice sousedství :

Cílem je vytvořit a SPT (strom nejkratší cesty) s daným zdrojem jako kořenem. Udržujte matici sousedství se dvěma sadami,

  • jedna sada obsahuje vrcholy zahrnuté ve stromu nejkratší cesty,
  • další sada obsahuje vrcholy, které ještě nejsou zahrnuty ve stromu nejkratší cesty.

V každém kroku algoritmu najděte vrchol, který je v druhé množině (množina ještě není zahrnuta) a má minimální vzdálenost od zdroje.

Algoritmus :

  • Vytvořte sadu sptSet (sada stromu nejkratších cest), která sleduje vrcholy zahrnuté ve stromu nejkratších cest, tj. jejichž minimální vzdálenost od zdroje je vypočtena a finalizována. Zpočátku je tato sada prázdná.
  • Přiřaďte hodnotu vzdálenosti všem vrcholům ve vstupním grafu. Inicializujte všechny hodnoty vzdálenosti jako NEKONEČNÝ . Přiřaďte hodnotu vzdálenosti jako 0 pro zdrojový vrchol, aby byl vybrán jako první.
  • Zatímco sptSet nezahrnuje všechny vrcholy
    • Vyberte vrchol v která tam není sptSet a má minimální hodnotu vzdálenosti.
    • Zahrňte vás do sptSet .
    • Potom aktualizujte hodnotu vzdálenosti všech sousedních vrcholů v .
      • Chcete-li aktualizovat hodnoty vzdálenosti, iterujte přes všechny sousední vrcholy.
      • Pro každý sousední vrchol v, pokud součet hodnoty vzdálenosti v (ze zdroje) a hmotnost hrany u-v , je menší než hodnota vzdálenosti v a poté aktualizujte hodnotu vzdálenosti v .

Poznámka: Používáme booleovské pole sptSet[] reprezentovat množinu zahrnutých vrcholů SPT . Pokud hodnota sptSet[v] je true, pak je zahrnut vrchol v SPT , jinak ne. Pole dist[] slouží k uložení hodnot nejkratší vzdálenosti ze všech vrcholů.

Ilustrace Dijkstrova algoritmu :

Abychom porozuměli Dijkstrově algoritmu, udělejte si graf a najděte nejkratší cestu od zdroje ke všem uzlům.

Zvažte níže uvedený graf a src = 0

1-(2)

Krok 1:

hashtable versus hashmap
  • Sada sptSet je zpočátku prázdný a vzdálenosti přiřazené k vrcholům jsou {0, INF, INF, INF, INF, INF, INF, INF} kde INF označuje nekonečno.
  • Nyní vyberte vrchol s minimální hodnotou vzdálenosti. Je vybrán vrchol 0, zahrňte ho sptSet . Tak sptSet se změní na {0}. Po zahrnutí 0 až sptSet , aktualizujte hodnoty vzdálenosti jeho sousedních vrcholů.
  • Sousední vrcholy 0 jsou 1 a 7. Hodnoty vzdálenosti 1 a 7 jsou aktualizovány jako 4 a 8.

Následující podgraf ukazuje vrcholy a jejich hodnoty vzdálenosti, jsou zobrazeny pouze vrcholy s hodnotami konečných vzdáleností. Vrcholy zahrnuté v SPT jsou zobrazeny v zelená barva.

6


Krok 2:

  • Vyberte vrchol s minimální hodnotou vzdálenosti, který ještě není zahrnut SPT (ne v sptSET ). Vrchol 1 je vybrán a přidán sptSet .
  • Tak sptSet nyní se změní na {0, 1}. Aktualizujte hodnoty vzdálenosti sousedních vrcholů na 1.
  • Hodnota vzdálenosti vrcholu 2 se stane 12 .
    4


Krok 3:

  • Vyberte vrchol s minimální hodnotou vzdálenosti, který ještě není zahrnut SPT (ne v sptSET ). Je vybrán Vertex 7. Tak sptSet nyní se stává {0, 1, 7}.
  • Aktualizujte hodnoty vzdálenosti sousedních vrcholů 7. Hodnota vzdálenosti vrcholů 6 a 8 se stane konečnou ( 15 a 9 respektive).
    5


Krok 4:

  • Vyberte vrchol s minimální hodnotou vzdálenosti, který ještě není zahrnut SPT (ne v sptSET ). Je vybrán Vertex 6. Tak sptSet nyní se stává {0, 1, 7, 6} .
  • Aktualizujte hodnoty vzdálenosti sousedních vrcholů 6. Hodnoty vzdálenosti vrcholu 5 a 8 se aktualizují.
    3-(1)


Výše uvedené kroky opakujeme, dokud sptSet zahrnuje všechny vrcholy daného grafu. Nakonec dostaneme následující S hortest Path Tree (SPT).

2-(2)

Níže je uvedena implementace výše uvedeného přístupu:

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; }>
Jáva
// 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>
Krajta
# 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 a sptSet[y] == False a  dist[y]> dist[x] + self.graph[x][y]: dist[y] = dist[x] + self.graph[x][y] self.printSolution(dist) # Kód řidiče 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) # Tento kód přispěl Divyanshu Mehta a aktualizoval Pranav Singh Sambyal>
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>

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

Časová náročnost: O(V2)
Pomocný prostor: O(V)

Poznámky:

řetězec java
  • Kód vypočítá nejkratší vzdálenost, ale nevypočítá informace o cestě. Vytvořte nadřazené pole, aktualizujte nadřazené pole, když se aktualizuje vzdálenost, a použijte jej k zobrazení nejkratší cesty od zdroje k různým vrcholům.
  • Časová náročnost realizace je O(V 2 ) . Pokud je vstup graf je znázorněn pomocí seznamu sousedství , může být redukován na O(E * log V) pomocí binární haldy. Prosím podívej se Dijkstrův algoritmus pro reprezentaci seznamu sousedství Více podrobností.
  • Dijkstrův algoritmus nefunguje pro grafy se zápornými váhovými cykly.

Proč Dijkstrovy algoritmy selhávají u grafů, které mají negativní hrany?

Problém se zápornými vahami vyplývá ze skutečnosti, že Dijkstrův algoritmus předpokládá, že jakmile je uzel přidán do množiny navštívených uzlů, jeho vzdálenost je finalizována a nemění se. V případě záporných vah však může tento předpoklad vést k nesprávným výsledkům.

Vezměme si jako příklad následující graf:

Selhání-Dijkstra-v-případě-negativních-hran

Ve výše uvedeném grafu je A zdrojový uzel mezi hranami A na B a A na C , A na B je menší hmotnost a Dijkstra přiřazuje nejkratší vzdálenost B jako 2, ale kvůli existenci záporné hrany od C na B skutečná nejkratší vzdálenost se sníží na 1, kterou Dijkstra nedokáže detekovat.

Poznámka: Používáme Algoritmus nejkratší cesty Bellmana Forda v případě, že máme v grafu záporné hrany.

Použití Dijkstrova algoritmu Seznam sousedství v O(E logV):

Pro Dijkstrův algoritmus se vždy doporučuje použít Kdykoli se zmenší vzdálenost vrcholu, přidáme další instanci vrcholu do priority_queue. I když existuje více instancí, bereme v úvahu pouze instanci s minimální vzdáleností a ignorujeme ostatní instance.

  • Časová složitost zůstává O(E * LogV) protože v prioritní frontě bude nejvýše O(E) vrcholů a O(logE) je stejné jako O(logV)
  • Níže je uvedena implementace výše uvedeného přístupu:

    C++
    // C++ Program to find Dijkstra's shortest path using // priority_queue in STL #include  using namespace std; #define INF 0x3f3f3f3f // iPair ==>Integer Pair typedef pair iPair; // Tato třída představuje orientovaný graf pomocí // reprezentace seznamu sousedství class Graph { int V; // Počet vrcholů // Ve váženém grafu potřebujeme uložit vrchol // a váhový pár pro každý seznam hran>* adj; veřejnost: Graf(int V); // Konstruktor // funkce pro přidání hrany do grafu void addEdge(int u, int v, int w);  // vypíše nejkratší cestu z s void shortestPath(int s); }; // Alokuje paměť pro seznam sousedství Graph::Graph(int V) { this->V = V;  adj = nový seznam [PROTI]; } 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)); } // Vytiskne nejkratší cesty od src ke všem ostatním vrcholům void Graph::shortestPath(int src) { // Vytvoří prioritní frontu pro uložení vrcholů, které // jsou předzpracovány. To je divná syntaxe v C++.  // Podrobnosti o této syntaxi naleznete na níže uvedeném odkazu // https://www.techcodeview.com priority_queue , větší > pq;  // Vytvořte vektor pro vzdálenosti a inicializujte všechny // vzdálenosti jako nekonečný (INF) vektor dist(V, INF);  // Vloží samotný zdroj do prioritní fronty a inicializuje // jeho vzdálenost jako 0. pq.push(make_pair(0, src));  dist[src] = 0;  /* Opakování, dokud se prioritní fronta nevyprázdní (nebo nejsou dokončeny všechny vzdálenosti) */ while (!pq.empty()) { // První vrchol v páru je minimální vzdálenost // vrchol, extrahujte jej z prioritní fronty.  // štítek vrcholu je uložen v sekundě z páru (to // musí být provedeno tímto způsobem, aby se zachovaly vrcholy // seřazená vzdálenost (vzdálenost musí být první položka // v páru) int u = pq.top().second; pq.pop(); // 'i' se používá k získání všech sousedních vrcholů // seznamu vrcholů>::iterátor i;  for (i = adj[u].begin(); i != adj[u].end(); ++i) { // Získání štítku vrcholu a váhy aktuálního // sousedícího s u.  int v = (*i).první;  int váha = (*i).sekunda;  // Pokud existuje zkrácená cesta k v přes u.  if (dist[v]> dist[u] + hmotnost) { // Aktualizace vzdálenosti v dist[v] = dist[u] + hmotnost;  pq.push(make_pair(dist[v], v));  } } } // Tisk nejkratších vzdáleností uložených v dist[] printf('Vzdálenost vrcholu od zdroje
    ');  for (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; }>
    Jáva
    import java.util.*; class Graph {  private int V;  private List> adj;  Graph(int V) { this.V = V;  adj = new ArrayList();  for (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 = nový 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('Vzdálenost vrcholu od zdroje');  for (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);  } }>
    Krajta
    import heapq # iPair ==>Integer Pair iPair = n-tice # Tato třída představuje orientovaný graf pomocí # třídy zobrazení seznamu sousedství Graf: 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)) # Vytiskne nejkratší cesty z src do všech ostatních vrcholů def shortestPath(self, src: int): # Vytvořte prioritní frontu pro uložení vrcholů, které # jsou předzpracovány pq = [] heapq.heappush(pq, (0, src)) # Vytvořte vektor pro vzdálenosti a inicializujte všechny # vzdálenosti jako nekonečné (INF) dist = [float('inf')] * self.V dist[src] = 0 zatímco pq: # První vrchol v páru je minimální vzdálenost # vertex, extrahujte jej z prioritní fronty. # štítek vrcholu je uložen v sekundě páru d, u = heapq.heappop(pq) # 'i' se používá k získání všech sousedních vrcholů # vrcholu pro v, váha v self.adj[u]: # If tam je zkrácená cesta k v přes u. if dist[v]> dist[u] + hmotnost: # Aktualizace vzdálenosti v dist[v] = dist[u] + hmotnost heapq.heappush(pq, (dist[v], v)) # Tisk nejkratších vzdáleností uložených v dist[] for i in range(self.V): print(f'{i} 		 {dist[i]}') # Kód řidiče if __name__ == '__main__': # vytvořte graf uvedený na obrázku výše V = 9 g = Graph(V) # vytvořte výše uvedený graf 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 Graf(int V) { // Počet vrcholů this.V = V;  // Ve váženém grafu potřebujeme uložit vrchol // a váhový pár pro každou hranu this.adj = new List [PROTI];  for (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 });  } // Vytiskne nejkratší cesty z src ke všem ostatním vrcholům public void ShortestPath(int src) { // Vytvoří prioritní frontu pro uložení vrcholů, které // jsou předzpracovány.  SortedSet pq = nová SortedSet (nový DistanceComparer());  // Vytvořte pole pro vzdálenosti a inicializujte všechny // vzdálenosti jako nekonečné (INF) int[] dist = new int[V];  for (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) { // První vrchol v páru je minimální vzdálenost // vrchol, extrahujte jej z prioritní fronty.  // štítek vrcholu je uložen v sekundě páru (to // musí být provedeno tímto způsobem, aby byly vrcholy // seřazeny podle vzdálenosti) int[] minDistVertex = pq.Min;  pq.Remove(minDistVertex);  int u = minDistVertex[1];  // 'i' se používá k získání všech sousedních vrcholů // vrcholu foreach (int[] adjVertex v tomto.adj[u]) { // Získání štítku vrcholu a váhy aktuálního // sousedícího s u.  int v = adjVertex[0];  int váha = adjVertex[1];  // Pokud existuje kratší cesta k v přes u.  if (dist[v]> dist[u] + hmotnost) { // Aktualizace vzdálenosti v dist[v] = dist[u] + hmotnost;  pq.Add(new int[] { dist[v], v });  } } } // Tisk nejkratších vzdáleností uložených v dist[] Console.WriteLine('Vzdálenost vrcholu od zdroje');  for (int i = 0; i< V; ++i)  Console.WriteLine(i + '	' + dist[i]);  }  private class DistanceComparer : IComparer { public int Porovnej(int[] x, int[] y) { if (x[0] == y[0]) { return x[1] - y[1];  } return x[0] - y[0];  } } } public class Program { // Kód ovladače public static void Main() { // vytvořte graf uvedený na obrázku výše int V = 9;  Graph g = new Graph(V);  // vytvoření výše uvedeného grafu 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);  } } // tento kód přispěl bhardwajji>
    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) { // První vrchol v páru je minimální vzdálenost // vrchol, extrahujte jej z prioritní fronty.  // štítek vrcholu je uložen ve druhém z páru (to // musí být provedeno tímto způsobem, aby byly zachovány vrcholy // seřazená vzdálenost (vzdálenost musí být první položka // v páru) let u = pq[0][1]; pq.shift() // 'i' se používá k získání všech sousedních vrcholů // vrcholu for(ať 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] + váha) { // Aktualizace vzdálenosti v dist[v] = dist[u] + váha;  pq.push([dist[v], v]);  pq.sort((a, b) =>{ if(a[0] == b[0]) return a[1] - b[1]; return a[0] - b[0]; });  } } } // Tisk nejkratších vzdáleností uložených v dist[] console.log('Vzdálenost vrcholu od zdroje');  for (ať 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.>

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

    Časová náročnost: O(E * logV), kde E je počet hran a V je počet vrcholů.
    Pomocný prostor: O(V)

    Aplikace Dijkstrova algoritmu:

    • Google mapy používá Dijkstrův algoritmus k zobrazení nejkratší vzdálenosti mezi zdrojem a cílem.
    • v počítačové sítě , Dijkstrův algoritmus tvoří základ pro různé směrovací protokoly, jako je OSPF (otevřená nejkratší cesta) a IS-IS (mezilehlý systém k mezilehlému systému).
    • Dopravní systémy a systémy řízení provozu využívají Dijkstrův algoritmus k optimalizaci dopravního toku, minimalizaci kongescí a plánování nejúčinnějších tras pro vozidla.
    • Letecké společnosti používají Dijkstrův algoritmus k plánování letových tras, které minimalizují spotřebu paliva a zkracují dobu cestování.
    • Dijkstrův algoritmus se používá v automatizaci elektronického návrhu pro směrování spojení na integrovaných obvodech a čipech velmi rozsáhlé integrace (VLSI).

    Podrobnější vysvětlení naleznete v tomto článku Dijkstrův algoritmus nejkratší cesty pomocí priority_queue STL .

    jak stahovat hudbu