본문 바로가기
카테고리 없음

플로이드-워셜(Floyd-Warshall) (모든 정점 간의 최단 경로)

by kguidebook0001 2026. 2. 20.

앞서 우리는 다익스트라(Dijkstra) 알고리즘을 통해 '어느 한 출발 도시'에서 '나머지 모든 도시'로 가는 최단 경로를 구하는 방법을 배웠습니다. 하지만 현실의 비즈니스 요구사항은 훨씬 가혹합니다. 만약 서울에서 부산을 가는 최단 거리뿐만 아니라, "지도상에 존재하는 대전, 대구, 광주 등 모든 도시에서 출발하여 또 다른 모든 도시로 도착하는 최단 거리를 하나의 표(Matrix)로 싹 다 뽑아주세요"라는 요청이 들어오면 어떻게 해야 할까요? 다익스트라 알고리즘을 N번 반복해서 돌릴 수도 있겠지만, 코드가 몹시 지저분해지고 로직이 복잡해집니다. 이럴 때 불과 세 줄의 반복문만으로 마법처럼 모든 정점 간의 최단 경로를 한 번에 계산해 내는 우아한 알고리즘이 바로 '플로이드-워셜(Floyd-Warshall)'입니다.

1. 플로이드-워셜 알고리즘이란? (All-Pairs Shortest Path)

플로이드-워셜은 그래프에 존재하는 '모든 정점'에서 '모든 정점'으로 가는 최단 거리를 구하는 궁극의 길찾기 알고리즘입니다. 다익스트라가 그리디(Greedy) 방식에 기반한다면, 플로이드-워셜은 철저하게 동적 계획법(DP)의 원리를 따릅니다. 또한, 다익스트라가 절대 소화하지 못하는 '음수 가중치(-)' 간선이 존재하더라도 정상적으로 최단 거리를 구해낼 수 있다는 엄청난 장점을 지니고 있습니다. (단, 무한 루프에 빠지는 음수 사이클이 없다는 전제하에 가능합니다.)

2. 알고리즘의 심장: "거쳐 가는 정점(K)"의 마법

플로이드-워셜 알고리즘의 아이디어는 문장 한 줄로 요약될 만큼 매우 심플합니다. "A에서 B로 곧장 다이렉트로 가는 길보다, 중간에 K라는 정점을 한 번 거쳐서 가는 길이 혹시 더 빠르지 않을까?" 바로 이 질문을 모든 노드에 대해 던지는 것입니다.

2-1. 2차원 최단 거리 배열과 점화식

모든 노드 간의 거리를 담아야 하므로 2차원 배열 dist[i][j]를 선언합니다. 초기에는 자신에게 가는 거리는 0, 직접 연결된 길은 그 비용, 길이 없는 곳은 무한대(Infinity)로 채워 넣습니다.

그리고 대망의 핵심 점화식을 수행합니다.

// 점화식: i에서 j로 가는 거리와, i에서 k를 거쳐 j로 가는 거리를 비교하여 최솟값 갱신dist[i][j] = Math.min(dist[i][j], dist[i][k] + dist[k][j])

2-2. 3중 반복문의 우아한 구조

플로이드-워셜의 실제 코드는 컴퓨터 공학을 통틀어 가장 간결하고 아름다운 형태 중 하나로 꼽힙니다. 단 3개의 중첩된 for문으로 구현됩니다.

// K: 거쳐 가는 중간 노드 (가장 바깥쪽 루프여야 함이 절대적으로 중요!)for (int k = 1; k <= N; k++) {// I: 출발 노드for (int i = 1; i <= N; i++) {// J: 도착 노드for (int j = 1; j <= N; j++) {// k를 거쳐가는 게 더 빠르다면 거리 갱신if (dist[i][k] + dist[k][j] < dist[i][j]) {dist[i][j] = dist[i][k] + dist[k][j];}}}}

여기서 초보자들이 99% 확률로 저지르는 실수가 있습니다. 바로 '거쳐 가는 노드인 K'를 가장 바깥쪽 루프에 두지 않고 안쪽에 두는 것입니다. 플로이드-워셜은 "1번 노드를 거쳐 갈 때의 모든 맵을 갱신하고, 그 결과를 바탕으로 2번 노드를 거쳐 갈 때를 갱신하는 식"으로 DP가 쌓여나가야 합니다. K가 안쪽으로 들어가면, 아직 갱신되지도 않은 과거의 데이터를 참조하게 되어 완전히 엉터리 거리가 계산됩니다.

3. 시간 복잡도의 압박과 실무적 한계 (O(V^3))

코드가 이토록 짧고 구현이 쉬우며 모든 경로를 구해주는 완벽한 알고리즘이지만, 치명적인 단점이 하나 있습니다. 바로 3중 반복문에서 비롯되는 O(V^3)이라는 무지막지한 시간 복잡도입니다. 정점(노드)의 개수가 $V$일 때, 100개면 100만 번, 500개면 1억 2,500만 번의 연산을 수행해야 합니다.따라서 코딩 테스트나 실무 아키텍처 설계 시, 플로이드-워셜은 전체 노드의 개수가 최대 500개 이하일 정도로 매우 규모가 작은 그래프 환경에서만 사용해야 한다는 엄격한 제한을 스스로 걸어두어야 합니다. 노드가 수만 개를 넘어가는 일반적인 지도 데이터에서는 다익스트라나 A* 알고리즘을 반복 적용하는 것이 훨씬 현명한 선택입니다.

[핵심 요약]1. 플로이드-워셜(Floyd-Warshall) 알고리즘은 단 한 번의 실행으로 '모든 정점에서 모든 정점까지'의 최단 경로를 구해주는 강력한 DP 알고리즘입니다.2. 다익스트라와 달리 음수 가중치 간선이 있어도 동작하며, 코드는 3중 for문이라는 매우 간결하고 우아한 형태를 띱니다.3. 중간 기착지 K를 반드시 가장 바깥쪽 반복문에 두어야 하며, 시간 복잡도가 O(V^3)으로 매우 무거워 노드 개수가 적을 때만 사용 가능합니다.