1.イラスト例
例 1
次の図には 4 つの点 ABCD があり、A から各点までの最短経路を求めます。
- 最初に、最後の A から各点までの最短経路であるレコード (最後にレコード) を準備します。最初は空です。
- Aを起点として、AからB、C、Dに直接到達できます。AからBへの経路は2、Cへの経路は5、Dへの経路は3です。「レコード1」は次のようになります。以下に続きます:
- A→B:2
- A→C:5
- A→D:3
最短パス A→B: 2 を「最後に記録」に移動すると、「最後に記録」は A→B: 2 になります。
- 地点 B は C に移動できます: B→C: 4、 A から C は B から転送することを選択できます: この時点では A→C: 2+4=6, 6>5 であるため、「レコード 1」は更新されません( B→C:2と仮定すると、この時点ではA→C:2+2=4、4<5、その後「レコード1」を更新: A→C:4 )
- D点はCに行くことができます:D→C:3、 AからCに移動することを選択できます:このとき、A→C:3+3=6、6>5なので、「レコード1」は更新されていない
- 点 C には到達可能な点がありません。計算を終了します。
- 「レコード 1」を「最終的にレコード」に結合します。
- 最後に、A から各点への最短経路が得られます: A→B: 2、A→C: 5、A→D: 3 (仮定が正しい場合、「最終的な記録」は A→B: 2、A となります) →C:4.A→D:3)
例 2
次の図に示すように、A から各点までの最短経路を見つけます。
インスタンス 1 のレコードは最終的にセット S として記録され、最初の S には開始点のみが含まれます。集合 U の始点以外の点を記録します。隣接するノードはパス値を記録でき、隣接しないノードは ∞ として記録されます。すると、次の図は次のように表されます。
S={ A(0) },U={ B(4), C(2), D(3), E(∞), F(∞), G(∞), H(∞), I(∞ ) }
最初の一歩:
- S={ A(0) }
- U={ B(4), C(2) , D(3), E(∞), F(∞), G(∞), H(∞), I(∞) }
ステップ 2: C パスは前のステップで最短であり、2 です。
- S={ A(0), C(2) }
- U={ B(4), D(3) , E(2+3=5), F(2+2=4), G(∞), H(∞), I(∞) }
3 番目のステップ: D パスは前のステップで最も短く、3 です。
- S={ A(0), C(2), D(3) }
- U={ B(4) , E(5) , F(4) , G(∞) , H(∞) , I(3+5=8) }
ステップ 4: 前のステップでは、パス B と F が最短であり、4 です。
- S={ A(0), C(2), D(3), B(4) }
- U={ E(5), F(4) , G(4+5=9), H(∞), I(8) }
ステップ 5: 前のステップの F パスは最短で、4 です。
- S={ A(0)、C(2)、D(3)、B(4)、F(4) }
- U={ E(5) , G(9) , H(4+2=6) , I(8) }
ステップ 6: 前のステップの E パスが最短で、5 です。
- S={ A(0)、C(2)、D(3)、B(4)、F(4)、E(5) }
- U={ G(5+3=8), H(6) , I(8) }
ステップ 7: 前のステップの H パスは最短で、6 です。
- S={ A(0)、C(2)、D(3)、B(4)、F(4)、E(5)、H(6 ) }
- U={ G(6+1=7) , I(8) }
ステップ 8: 前のステップの G パスは最短で、7 です。
- S={ A(0), C(2), D(3), B(4), F(4), E(5), H(6), G(7 ) }
- U={ I(8) }
ステップ 9: 前のステップの I パスは最短で、8 です。
- S={ A(0)、C(2)、D(3)、B(4)、F(4)、E(5)、H(6)、G(7)、I(8 ) }
- U={ }
これまでに、A から各点までの最短経路が得られました。
2、JSコードの実装
例としてインスタンス 2 を取り上げます。
- まず、各点までの距離を記録するグラフ配列を定義します。次に例を示します。
- A→Aの距離は0、A→Bの距離は4、A→Cの距離は2、A→Dの距離は3、A→Eは隣接していないので距離は0・・・。
- B→Aは不可逆なので距離は0、B→Bの距離は0、B→Cの距離は1、B→Dは隣接していないので距離は0…。
等々
let graph = [
[0,4,2,3,0,0,0,0,0],
[0,0,1,0,0,0,5,0,0],
[0,0,0,0,3,2,0,0,0],
[0,0,1,0,0,1,0,0,5],
[0,0,0,0,0,0,3,2,0],
[0,0,0,0,1,0,0,2,0],
[0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,1,0,0],
[0,0,0,0,0,0,0,1,0]
]
- 現在知られている最短パスを記録する currentMinPth 配列を定義し、初期値は無限大です。visited 配列を定義し、それが訪問されたかどうかを記録し、訪問された次のサイクルは訪問しません。
let currentMinPth = [];
let visited = [];
for(let i = 0; i < graph.length;i++){
currentMinPth.push(INF);
visited.push(false);
}
- 開始点は A で、A→A は 0 なので、currentMinPth[0] は 0 になります。
- 現在既知のノードから最も近いノードを検索し、インデックス値 minIndex を返します (毎回最短パスから開始)
function getMinIndex(currentMinPth,visited){
let min = INF;
let minIndex = -1;
for(let i = 0; i < currentMinPth.length;i++){
if(!visited[i]&¤tMinPth[i]<min){
min = currentMinPth[i];
minIndex = i;
}
}
return minIndex
}
- 取得した最も近いノードを訪問済みとして設定します。
visited[minIndex] = true;
- 隣接ノード、つまり、graph[minIndex][i] !== 0 であるノードを検索し、隣接ノードへのパス値を currentMinPth に更新します。ただし、この値が現在の値より小さい場合に限ります。
if(!visited[i]&&
graph[minIndex][i] !== 0 &&
currentMinPth[minIndex] + graph[minIndex][i] < currentMinPth[i]){
currentMinPth[i] = currentMinPth[minIndex] + graph[minIndex][i];
}
- currentMinPth の各項目に対して上記のプロセスを繰り返します。長さ - 1 で十分です。最後の 1 つだけが残っている場合はチェックする必要はありません。完全なコードは次のとおりです。
let graph = [
[0,4,2,3,0,0,0,0,0],
[0,0,1,0,0,0,5,0,0],
[0,0,0,0,3,2,0,0,0],
[0,0,1,0,0,1,0,0,5],
[0,0,0,0,0,0,3,2,0],
[0,0,0,0,1,0,0,2,0],
[0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,1,0,0],
[0,0,0,0,0,0,0,1,0]
]
let INF = Number.MAX_SAFE_INTEGER;
function handlePath(){
let currentMinPth = [];
let visited = [];
for(let i = 0; i < graph.length;i++){
currentMinPth.push(INF);
visited.push(false);
}
currentMinPth[0] = 0
for(let j = 0; j < currentMinPth.length - 1;j++){
let minIndex = getMinIndex(currentMinPth,visited);
visited[minIndex] = true;
for(let i = 0; i < currentMinPth.length;i++){
if(!visited[i]&&
graph[minIndex][i] !== 0 &&
currentMinPth[minIndex] + graph[minIndex][i] < currentMinPth[i]){
currentMinPth[i] = currentMinPth[minIndex] + graph[minIndex][i];
}
}
}
return currentMinPth
}
function getMinIndex(currentMinPth,visited){
let min = INF;
let minIndex = -1;
for(let i = 0; i < currentMinPth.length;i++){
if(!visited[i]&¤tMinPth[i]<min){
min = currentMinPth[i];
minIndex = i;
}
}
return minIndex
}
console.log(handlePath())
要約する
この記事はダイクストラの最短経路原理の簡単な理解とjsのコード実装を記録したものです、間違いがあればご指摘ください!