記事のディレクトリ
ダイクストラのアルゴリズムにより、グラフの任意の2つの頂点間の最短経路を見つけることができます。
2つの頂点間の最短距離にグラフのすべての頂点が含まれない場合があるため、最小全域木とは異なります。
ダイクストラのアルゴリズムのしくみ
ダイクストラのアルゴリズムの動作原理は、頂点AとDの間の最短経路A-> Dの特定のサブパスB-> Dが、頂点BとDの間の最短経路でもあるということです。
ダイクストラはこのプロパティを逆に使用します。つまり、各頂点から開始頂点までの距離を過大評価します。次に、各ノードとそのネイバーにアクセスし、これらのネイバーへの最短のサブパスを見つけます。
アルゴリズムは欲張り法を使用します。つまり、最終結果が問題全体の最良の解決策になることを期待して、最良の解決策を探します。
ダイクストラのアルゴリズムの例
例から始めて、アルゴリズムを検討する方が簡単です。
加重グラフから始めます。
開始頂点を選択し、無限パス値を他のすべてのノードに割り当てます。
各頂点のパス長を更新します。
隣接する頂点のパスの長さが新しいパスの長さよりも短い場合、更新されません。
訪問した頂点のパス長を更新しないでください。
各反復の後、パスの長さが最小の未訪問の頂点を選択します。したがって、7の前に5を選択します。
右端の頂点のパス長が2回更新されていることに注目してください。
すべての頂点にアクセスするまで繰り返します。
ダイクストラアルゴリズムの擬似コード
各頂点のパス距離を維持する必要があります。サイズvの配列に格納できます。ここで、vは頂点の数です。
また、最短経路の長さだけでなく、最短経路を取得したいと考えています。これを行うには、各頂点を、パスの長さが最後に更新された頂点にマップします。
アルゴリズムが終了したら、ターゲット頂点からソース頂点にバックトラックしてパスを見つけることができます。
最小の優先度キューは、最小のパス距離で頂点を効果的に受信できます。
function dijkstra(G, S)
for each vertex V in G
distance[V] <- infinite
previous[V] <- NULL
If V != S, add V to Priority Queue Q
distance[S] <- 0
while Q IS NOT EMPTY
U <- Extract MIN from Q
for each unvisited neighbour V of U
tempDistance <- distance[U] + edge_weight(U, V)
if tempDistance < distance[V]
distance[V] <- tempDistance
previous[V] <- U
return distance[], previous[]
ダイクストラアルゴリズムコード
// Dijkstra's Algorithm in C
#include <stdio.h>
#define INFINITY 9999
#define MAX 10
void Dijkstra(int Graph[MAX][MAX], int n, int start);
void Dijkstra(int Graph[MAX][MAX], int n, int start) {
int cost[MAX][MAX], distance[MAX], pred[MAX];
int visited[MAX], count, mindistance, nextnode, i, j;
// Creating cost matrix
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
if (Graph[i][j] == 0)
cost[i][j] = INFINITY;
else
cost[i][j] = Graph[i][j];
for (i = 0; i < n; i++) {
distance[i] = cost[start][i];
pred[i] = start;
visited[i] = 0;
}
distance[start] = 0;
visited[start] = 1;
count = 1;
while (count < n - 1) {
mindistance = INFINITY;
for (i = 0; i < n; i++)
if (distance[i] < mindistance && !visited[i]) {
mindistance = distance[i];
nextnode = i;
}
visited[nextnode] = 1;
for (i = 0; i < n; i++)
if (!visited[i])
if (mindistance + cost[nextnode][i] < distance[i]) {
distance[i] = mindistance + cost[nextnode][i];
pred[i] = nextnode;
}
count++;
}
// Printing the distance
for (i = 0; i < n; i++)
if (i != start) {
printf("\nDistance from source to %d: %d", i, distance[i]);
}
}
int main() {
int Graph[MAX][MAX], i, j, n, u;
n = 7;
Graph[0][0] = 0;
Graph[0][1] = 0;
Graph[0][2] = 1;
Graph[0][3] = 2;
Graph[0][4] = 0;
Graph[0][5] = 0;
Graph[0][6] = 0;
Graph[1][0] = 0;
Graph[1][1] = 0;
Graph[1][2] = 2;
Graph[1][3] = 0;
Graph[1][4] = 0;
Graph[1][5] = 3;
Graph[1][6] = 0;
Graph[2][0] = 1;
Graph[2][1] = 2;
Graph[2][2] = 0;
Graph[2][3] = 1;
Graph[2][4] = 3;
Graph[2][5] = 0;
Graph[2][6] = 0;
Graph[3][0] = 2;
Graph[3][1] = 0;
Graph[3][2] = 1;
Graph[3][3] = 0;
Graph[3][4] = 0;
Graph[3][5] = 0;
Graph[3][6] = 1;
Graph[4][0] = 0;
Graph[4][1] = 0;
Graph[4][2] = 3;
Graph[4][3] = 0;
Graph[4][4] = 0;
Graph[4][5] = 2;
Graph[4][6] = 0;
Graph[5][0] = 0;
Graph[5][1] = 3;
Graph[5][2] = 0;
Graph[5][3] = 0;
Graph[5][4] = 2;
Graph[5][5] = 0;
Graph[5][6] = 1;
Graph[6][0] = 0;
Graph[6][1] = 0;
Graph[6][2] = 0;
Graph[6][3] = 1;
Graph[6][4] = 0;
Graph[6][5] = 1;
Graph[6][6] = 0;
u = 0;
Dijkstra(Graph, n, u);
return 0;
}
ダイクストラのアルゴリズムの複雑さ
時間計算量:O(E Log V)
ここで、Eはエッジの数、Vは頂点の数です。
スペースの複雑さ:O(V)
ダイクストラのアルゴリズムの適用
- 最短経路を見つける
- ソーシャルネットワークでのアプリケーション
- 電話網で
- 地図上で場所を探す
参考文献
[1]パレワラボPvt。Ltd.Dijkstraのアルゴリズム[EB / OL] .https://www.programiz.com/dsa/dijkstra-algorithm,2020-01-01。