알고리즘
다익스트라 알고리즘
탁재민
2024. 4. 13. 11:18
그래프에서 한 노드에서 다른 노드까지의 최단 경로를 찾기 위한 알고리즘
가중치가 있는 그래프에서 사용되며, 가중치는 음수가 아니어야 함
다익스트라 알고리즘의 기본 원리
- 초기화: 시작 노드의 거리를 0으로 설정하고, 나머지 모든 노드의 거리를 무한대로 설정
- 방문 처리: 아직 방문하지 않은 노드 중에서 가장 거리가 짧은 노드를 선택
- 경로 갱신: 선택된 노드를 경유하여 인접한 노드까지의 거리를 계산하고, 기존에 저장된 거리보다 짧다면 업데이트
- 반복: 모든 노드가 방문될 때까지 2번과 3번을 반복
배열 예제
function dijkstra(graph, start) {
const distances = Array(graph.length).fill(Infinity); // 모든 노드까지의 거리를 무한대로 초기화
const visited = Array(graph.length).fill(false); // 방문 여부를 기록하는 배열
distances[start] = 0; // 시작 노드의 거리를 0으로 설정
function getSmallestUnvisitedNode() {
let minDistance = Infinity;
let minNode = -1;
// 방문하지 않은 노드 중 가장 거리가 짧은 노드를 찾는다
for (let i = 0; i < graph.length; i++) {
if (!visited[i] && distances[i] < minDistance) {
minDistance = distances[i];
minNode = i;
}
}
return minNode;
}
for (let i = 0; i < graph.length - 1; i++) {
const node = getSmallestUnvisitedNode(); // 가장 거리가 짧은 노드를 선택
visited[node] = true; // 선택된 노드를 방문 처리
graph[node].forEach((edge) => {
const [neighbor, weight] = edge;
if (!visited[neighbor]) { // 방문하지 않은 이웃 노드에 대해서만 처리
const newDistance = distances[node] + weight;
if (newDistance < distances[neighbor]) { // 새로운 거리가 더 짧은 경우 업데이트
distances[neighbor] = newDistance;
}
}
});
}
return distances; // 모든 노드까지의 최단 거리 배열을 반환
}
우선순위 큐 예제
class MinHeap {
constructor() {
this.heap = [];
}
push(value) {
this.heap.push(value);
this.heap.sort((a, b) => a.distance - b.distance); // 힙에 새 요소를 추가하고 거리에 따라 정렬
}
pop() {
return this.heap.shift(); // 가장 작은 거리를 가진 요소를 제거하고 반환
}
isEmpty() {
return this.heap.length === 0; // 힙이 비어있는지 확인
}
}
function dijkstraWithHeap(graph, start) {
const distances = Array(graph.length).fill(Infinity); // 모든 노드까지의 거리를 무한대로 초기화
const minHeap = new MinHeap();
distances[start] = 0;
minHeap.push({ node: start, distance: 0 }); // 시작 노드를 힙에 추가
while (!minHeap.isEmpty()) {
const { node, distance } = minHeap.pop(); // 힙에서 거리가 가장 짧은 노드를 추출
if (distance > distances[node]) continue; // 현재 노드까지의 거리가 이미 더 짧은 경우 스킵
graph[node].forEach(([neighbor, weight]) => {
const newDistance = distances[node] + weight; // 새로운 거리 계산
if (newDistance < distances[neighbor]) { // 새로운 거리가 현재 거리보다 짧은 경우 업데이트
distances[neighbor] = newDistance;
minHeap.push({ node: neighbor, distance: newDistance }); // 업데이트된 거리와 함께 이웃 노드를 힙에 추가
}
});
}
return distances; // 모든 노드까지의 최단