logo

Dijkstra 알고리즘을 사용하여 소스에서 모든 정점까지의 최단 경로를 찾는 방법

가중치 그래프와 그래프의 소스 ​​정점이 주어지면 다음을 찾습니다. 최단 경로 소스에서 주어진 그래프의 다른 모든 정점까지.

메모: 주어진 그래프에는 음의 간선이 포함되어 있지 않습니다.

예:



입력: src = 0이면 그래프는 아래와 같습니다.

1-(2)

산출: 0 4 12 19 21 11 9 8 14
설명: 0에서 1까지의 거리 = 4.
0에서 2까지의 최소 거리 = 12. 0->1->2
0에서 3까지의 최소 거리 = 19. 0->1->2->3
0에서 4까지의 최소 거리 = 21. 0->7->6->5->4
0에서 5까지의 최소 거리 = 11. 0->7->6->5
0에서 6까지의 최소 거리 = 9. 0->7->6
0에서 7까지의 최소 거리 = 8. 0->7
0에서 8까지의 최소 거리는 14입니다. 0->1->2->8

Dijkstra 알고리즘 구현 권장 사례 시도해 보세요!

Dijkstra의 알고리즘을 사용하여 인접 행렬 :

아이디어는 SPT(최단 경로 트리) 주어진 소스를 루트로 사용합니다. 두 세트로 인접 행렬을 유지합니다.

  • 한 세트에는 최단 경로 트리에 포함된 정점이 포함됩니다.
  • 다른 세트에는 최단 경로 트리에 아직 포함되지 않은 정점이 포함됩니다.

알고리즘의 모든 단계에서 다른 세트(아직 포함되지 않은 세트)에 있고 소스로부터 최소 거리를 갖는 정점을 찾습니다.

이런, 자바에서

연산 :

  • 세트 만들기 sptSet (최단 경로 트리 집합)은 최단 경로 트리에 포함된 정점, 즉 소스로부터의 최소 거리가 계산되고 확정되는 정점을 추적합니다. 처음에 이 세트는 비어 있습니다.
  • 입력 그래프의 모든 정점에 거리 값을 할당합니다. 모든 거리 값을 다음과 같이 초기화합니다. 인피니트 . 소스 정점이 먼저 선택되도록 거리 값을 0으로 할당합니다.
  • 하는 동안 sptSet 모든 정점을 포함하지 않음
    • 정점 선택 ~에 그건 거기 없어 sptSet 최소 거리 값을 갖습니다.
    • 당신을 포함 sptSet .
    • 그런 다음 인접한 모든 정점의 거리 값을 업데이트합니다. ~에 .
      • 거리 값을 업데이트하려면 인접한 모든 정점을 반복합니다.
      • 모든 인접한 정점에 대해 안에, 거리 값의 합이 ~에 (소스에서) 및 가장자리의 무게 u-v 는 거리 값보다 작습니다. ~에 그런 다음 거리 값을 업데이트합니다. ~에 .

메모: 부울 배열을 사용합니다 spt세트[] 포함된 정점 집합을 나타냅니다. SPT . 값이 있는 경우 spt세트[v] 가 참이면 정점 v가 다음에 포함됩니다. SPT , 그렇지 않으면 그렇지 않습니다. 정렬 거리[] 모든 정점의 최단 거리 값을 저장하는 데 사용됩니다.

Dijkstra 알고리즘의 그림 :

Dijkstra 알고리즘을 이해하기 위해 그래프를 작성하고 소스에서 모든 노드까지의 최단 경로를 찾아 보겠습니다.

아래 그래프를 고려하고 소스 = 0

레지스터 전송 로직
1-(2)

1 단계:

  • 세트 sptSet 처음에는 비어 있고 정점에 할당된 거리는 {0, INF, INF, INF, INF, INF, INF, INF}입니다. INF 무한함을 나타냅니다.
  • 이제 최소 거리 값을 갖는 정점을 선택합니다. 정점 0이 선택되어 포함됩니다. sptSet . 그래서 sptSet {0}이 됩니다. 0부터 포함 후 sptSet , 인접한 정점의 거리 값을 업데이트합니다.
  • 0의 인접한 정점은 1과 7입니다. 1과 7의 거리 값은 4와 8로 업데이트됩니다.

다음 하위 그래프는 정점과 해당 거리 값을 보여 주며, 유한한 거리 값을 가진 정점만 표시됩니다. 에 포함된 정점 SPT 에 표시됩니다 녹색 색상.

6


2 단계:

  • 최소 거리 값을 가지며 아직 포함되지 않은 정점을 선택합니다. SPT (안에서 sptSET ). 정점 1이 선택되어 다음에 추가됩니다. sptSet .
  • 그래서 sptSet 이제 {0, 1}이 됩니다. 1의 인접한 정점의 거리 값을 업데이트합니다.
  • 정점 2의 거리 값은 다음과 같습니다. 12 .
    4


3단계:

  • 최소 거리 값을 가지며 아직 포함되지 않은 정점을 선택합니다. SPT (안에서 sptSET ). 정점 7이 선택되었습니다. 그래서 sptSet 지금은 된다 {0, 1, 7}.
  • 7의 인접한 정점의 거리 값을 업데이트합니다. 정점 6과 8의 거리 값은 유한해집니다( 15와 9 각기).
    5


4단계:

  • 최소 거리 값을 가지며 아직 포함되지 않은 정점을 선택합니다. SPT (안에서 sptSET ). 정점 6이 선택되었습니다. 그래서 sptSet 지금은 된다 {0, 1, 7, 6} .
  • 인접한 정점 6의 거리 값을 업데이트합니다. 정점 5와 8의 거리 값이 업데이트됩니다.
    3-(1)


우리는 위의 단계를 반복할 때까지 sptSet 포함 주어진 그래프의 모든 정점. 마지막으로 다음 S를 얻습니다. 최단 경로 트리(SPT).

2-(2)

다음은 위의 접근 방식을 구현한 것입니다.

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 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; }>
자바
// 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 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 및 sptSet[y] == False 및  dist[y]> dist[x] + self.graph[x][y]: dist[y] = dist[x] + self.graph[x][y] self.printSolution(dist) # 드라이버 코드 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) # 이 코드는 Divyanshu Mehta가 제공하고 Pranav Singh Sambyal이 업데이트함>
씨#
// 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>
자바스크립트
// 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>

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

시간 복잡도: 오(V2)
보조 공간: 오(V)

사용자에게 mysql 표시

노트:

  • 코드는 최단 거리를 계산하지만 경로 정보는 계산하지 않습니다. 상위 배열을 만들고, 거리가 업데이트되면 상위 배열을 업데이트하고, 이를 사용하여 소스에서 다른 정점까지의 최단 경로를 표시합니다.
  • 구현의 시간 복잡성은 다음과 같습니다. 오(V 2 ) . 입력된 경우 그래프는 인접 목록을 사용하여 표현됩니다. , 바이너리 힙을 사용하여 O(E * log V)로 줄일 수 있습니다. 참조하세요 인접 목록 표현을 위한 Dijkstra 알고리즘 상세 사항은.
  • Dijkstra의 알고리즘은 음수 가중치 주기를 갖는 그래프에서는 작동하지 않습니다.

음의 모서리가 있는 그래프에서 Dijkstra의 알고리즘이 실패하는 이유는 무엇입니까?

음수 가중치의 문제는 Dijkstra의 알고리즘이 노드가 방문한 노드 집합에 추가되면 해당 거리가 확정되고 변경되지 않을 것이라고 가정한다는 사실에서 발생합니다. 그러나 음수 가중치가 있는 경우 이 가정은 잘못된 결과를 초래할 수 있습니다.

예를 들어 다음 그래프를 고려하십시오.

네거티브 에지의 경우 Dijkstra 실패

위 그래프에서 A는 간선 중 소스 노드입니다. 에게 그리고 에게 , 에게 는 더 작은 가중치이고 Dijkstra는 가장 짧은 거리를 할당합니다. 2와 같지만 음의 가장자리가 존재하기 때문에 에게 , 실제 최단 거리는 Dijkstra가 감지하지 못하는 1로 감소합니다.

메모: 우리는 사용 Bellman Ford의 최단 경로 알고리즘 그래프에 음의 가장자리가 있는 경우.

Dijkstra의 알고리즘을 사용하여 인접 목록 O(E logV)에서:

Dijkstra 알고리즘의 경우 항상 다음을 사용하는 것이 좋습니다. 정점의 거리가 줄어들 때마다 Priority_queue에 정점의 인스턴스를 하나 더 추가합니다. 인스턴스가 여러 개 있더라도 최소 거리의 인스턴스만 고려하고 다른 인스턴스는 무시합니다.

테스트 유형
  • 시간복잡도는 남아 O(E * LogV) 우선순위 큐에는 최대 O(E)개의 정점이 있고 O(logE)는 O(logV)와 동일합니다.
  • 다음은 위의 접근 방식을 구현한 것입니다.

    C++
    // C++ Program to find Dijkstra's shortest path using // priority_queue in STL #include  using namespace std; #define INF 0x3f3f3f3f // iPair ==>정수 쌍 typedef 쌍 아이페어; // 이 클래스는 // 인접 목록 표현을 사용하여 유향 그래프를 나타냅니다. class Graph { int V; // 정점 수 // 가중치 그래프에서는 // 모든 간선 목록에 대해 정점과 가중치 쌍을 저장해야 합니다.>* 조정; 공개: 그래프(int V); // 생성자 // 그래프에 간선을 추가하는 함수 void addEdge(int u, int v, int w);  // s에서 최단 경로를 인쇄합니다. void shortestPath(int s); }; // 인접 목록에 대한 메모리 할당 Graph::Graph(int V) { this->V = V;  adj = 새 목록 [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)); } // src에서 다른 모든 정점까지의 최단 경로를 인쇄합니다. void Graph::shortestPath(int src) { // 전처리 중인 정점을 저장하기 위해 // 우선순위 대기열을 생성합니다. 이것은 C++의 이상한 구문입니다.  // 이 구문에 대한 자세한 내용은 아래 링크를 참조하세요. // https://www.techcodeview.com Priority_queue , 보다 큰 > pq;  // 거리에 대한 벡터를 생성하고 // 모든 거리를 무한(INF) 벡터로 초기화합니다. dist(V,INF);  // 소스 자체를 우선순위 큐에 삽입하고 // 거리를 0으로 초기화합니다. pq.push(make_pair(0, src));  거리[src] = 0;  /* 우선순위 큐가 비워질 때까지(또는 모든 거리가 확정되지 않을 때까지 반복) */ while (!pq.empty()) { // 쌍의 첫 번째 정점은 최소 거리입니다. // 정점, 우선순위 큐에서 추출합니다.  // 정점 레이블은 쌍의 두 번째 항목에 저장됩니다(정점을 유지하려면 // 이 방법을 사용해야 합니다. // 정렬된 거리(거리는 // 쌍의 첫 번째 항목이어야 합니다) int u = pq.top().second; pq.pop(); // 'i'는 정점 목록의 모든 인접 정점을 가져오는 데 사용됩니다.>::반복자 i;  for (i = adj[u].begin(); i != adj[u].end(); ++i) { // 정점 레이블과 현재 // u에 인접한 가중치를 가져옵니다.  int v = (*i).first;  int 가중치 = (*i).second;  // u를 통해 v로의 단축 경로가 있는 경우.  if (dist[v]> dist[u] + Weight) { // v의 거리 업데이트 dist[v] = dist[u] + Weight;  pq.push(make_pair(dist[v], v));  } } } // dist[]에 저장된 최단 거리를 인쇄합니다. printf('소스로부터의 정점 거리
    ');  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; }>
    자바
    import java.util.*; class Graph {  private int V;  private List> 조정;  그래프(int V) { this.V = V;  adj = 새로운 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 = 새로운 int[V];  Arrays.fill(dist, Integer.MAX_VALUE);  pq.add(새 iPair(0, src));  거리[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('소스로부터의 정점 거리');  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);  } }>
    파이썬
    import heapq # iPair ==>정수 쌍 iPair = tuple # 이 클래스는 # 인접 목록 표현 클래스를 사용하여 유향 그래프를 나타냅니다. Graph: def __init__(self, V: int): # 생성자 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)) # src에서 다른 모든 정점으로의 최단 경로를 인쇄합니다. def shortestPath(self, src: int): # 전처리 중인 정점을 저장하기 위해 우선순위 큐를 생성합니다. pq = [] heapq.heappush(pq, (0, src)) # 거리에 대한 벡터를 생성하고 # 모든 거리를 무한(INF)으로 초기화합니다. dist = [float('inf')] * self.V dist[src] = 0 while pq: # 쌍의 첫 번째 정점은 최소 거리입니다. # 정점, 우선순위 큐에서 추출합니다. # 정점 레이블은 쌍 d의 두 번째에 저장됩니다. u = heapq.heappop(pq) # 'i'는 a의 모든 인접한 정점을 가져오는 데 사용됩니다. # 정점 for v, 가중치 in self.adj[u]: # If u를 통해 v로 가는 단축 경로가 있습니다. if dist[v]> dist[u] + Weight: # v의 거리 업데이트 dist[v] = dist[u] + Weight heapq.heappush(pq, (dist[v], v)) # 저장된 최단 거리를 인쇄합니다. dist[] for i in range(self.V): print(f'{i} 		 {dist[i]}') # 드라이버의 코드 if __name__ == '__main__': # 위 그림에 주어진 그래프를 생성합니다. V = 9 g = 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)>
    씨#
    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 [] 조정;  public Graph(int V) { // 정점 수 this.V = V;  // 가중치 그래프에서는 정점과 // 모든 간선에 대한 가중치 쌍을 저장해야 합니다. this.adj = new List [V];  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 });  } // src에서 다른 모든 꼭짓점까지의 최단 경로를 인쇄합니다. public void ShortestPath(int src) { // 전처리 중인 꼭짓점을 저장하기 위해 // 우선순위 대기열을 만듭니다.  SortedSet pq = 새로운 SortedSet (새로운 DistanceComparer());  // 거리에 대한 배열을 만들고 // 모든 거리를 무한(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) { // 쌍의 첫 번째 정점은 최소 거리 // 정점이며 우선 순위 대기열에서 추출합니다.  // 정점 레이블은 두 번째 쌍으로 저장됩니다(정점을 유지하려면 // 이 방법을 수행해야 // 거리별로 정렬됨) int[] minDistVertex = pq.Min;  pq.Remove(minDistVertex);  int u = minDistVertex[1];  // 'i'는 정점의 모든 인접 정점을 가져오는 데 사용됩니다. // foreach (int[] adjVertex in this.adj[u]) { // 정점 레이블과 현재 // u 인접 정점의 가중치를 가져옵니다.  int v = adjVertex[0];  int 가중치 = adjVertex[1];  // u를 통해 v로 가는 더 짧은 경로가 있는 경우.  if (dist[v]> dist[u] + Weight) { // v의 거리 업데이트 dist[v] = dist[u] + Weight;  pq.Add(new int[] { dist[v], v });  } } } // dist[]에 저장된 최단 거리를 인쇄합니다. Console.WriteLine('소스로부터의 정점 거리');  for (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];  } x[0] - y[0]을 반환합니다.  } } } public class Program { // 드라이버 코드 public static void Main() { // 위 그림에 주어진 그래프를 생성합니다 int V = 9;  그래프 g = 새로운 그래프(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);  } } // 이 코드는 bhardwajji가 제공한 것입니다.>
    자바스크립트
    // 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) { // 쌍의 첫 번째 정점은 최소 거리 // 정점이며 우선 순위 대기열에서 추출합니다.  // 정점 레이블은 쌍 중 두 번째 항목에 저장됩니다(정점을 유지하려면 // 이 방법을 사용해야 합니다. // 정렬된 거리(거리는 // 쌍의 첫 번째 항목이어야 합니다) let u = pq[0][1]; pq.shift(); // 'i'는 정점의 모든 인접 정점을 가져오는 데 사용됩니다. // 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] + Weight) { // v의 거리 업데이트 dist[v] = dist[u] + Weight;  pq.push([dist[v], v]);  pq.sort((a, b) =>{ if(a[0] == b[0]) return a[1] - b[1]; return a[0] - b[0]; });  } } } // dist[]에 저장된 최단 거리를 인쇄합니다. console.log('소스로부터의 정점 거리');  for (나는 = 0이라고 하자; 나는< 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.>

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

    시간 복잡도: O(E * logV), 여기서 E는 모서리 수이고 V는 정점 수입니다.
    보조 공간: 오(V)

    Dijkstra 알고리즘의 응용:

    • 구글지도 Dijkstra 알고리즘을 사용하여 소스와 대상 사이의 최단 거리를 표시합니다.
    • ~ 안에 컴퓨터 네트워킹 , Dijkstra의 알고리즘은 OSPF(Open Shortest Path First) 및 IS-IS(Intermediate System to Intermediate System)와 같은 다양한 라우팅 프로토콜의 기반을 형성합니다.
    • 교통 및 교통 관리 시스템은 Dijkstra의 알고리즘을 사용하여 교통 흐름을 최적화하고 혼잡을 최소화하며 가장 효율적인 차량 경로를 계획합니다.
    • 항공사는 Dijkstra의 알고리즘을 사용하여 연료 소비를 최소화하고 여행 시간을 줄이는 비행 경로를 계획합니다.
    • Dijkstra의 알고리즘은 집적 회로 및 VLSI(Very Large Scale Integration) 칩의 라우팅 연결을 위한 전자 설계 자동화에 적용됩니다.

    자세한 설명은 이 글을 참고하세요 STL의 Priority_queue를 이용한 Dijkstra의 최단 경로 알고리즘 .