1. 예시 그림
예 1
다음 그림에는 4개의 점 ABCD가 있습니다. A에서 각 점까지의 최단 경로를 찾으십시오.
- 먼저 최종 A에서 각 지점까지의 최단 경로인 레코드(record finally)를 준비합니다. 처음에는 비어 있습니다.
- 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로, D에서 전송하도록 선택할 수 있습니다: 이때 A→C: 3+3=6, 6>5이므로 "레코드 1"은 업데이트되지 않음
- C 지점에 도달 가능한 지점이 없으므로 계산 종료
- "Record 1"을 "Record finally"로 병합
- 마지막으로 A에서 각 지점까지의 최단 경로를 얻습니다. A→B: 2, A→C: 5, A→D : 3 →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(∞) }
세 번째 단계: 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={ 지(6+1=7) , 나는(8) }
8단계: 이전 단계의 G 경로가 가장 짧은 7
- S={ A(0), C(2), D(3), B(4), F(4), E(5), H(6), G(7 ) }
- 유={ 나(8) }
9단계: 이전 단계의 I 경로가 가장 짧은 8
- S={ A(0), C(2), D(3), B(4), F(4), E(5), H(6), G(7), I(8 ) }
- 유={ }
지금까지 A에서 각 지점까지의 최단 경로를 구했습니다.
둘째, 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 배열을 정의하고 초기값은 무한대, 방문 배열을 정의하고 방문 여부를 기록하며 다음 방문 주기는 방문하지 않음
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이면 충분합니다. 마지막 하나만 남았을 때 확인할 필요가 없습니다. 전체 코드는 다음과 같습니다.
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())
요약하다
이 글은 Dijkstra의 최단 경로 원리에 대한 간단한 이해와 js의 코드 구현을 기록한 것입니다.