- 모든 정점에서 모든 정점까지의 최단 경로를 구하는 알고리즘
- 음의 가중치가 있어도 가능 (최종값이 음수일 경우 불가 → 음의 사이클)
- 동적 프로그래밍 방식 사용
- 간선을 직접 따라가는 대신, 중간 정점을 하나씩 고려해가며 경로를 갱신함
1. 알고리즘 동작 과정
- 최단 거리 배열을 초기화
- 자기 자신으로 가는 거리: 0
- 간선 존재 시 가중치 입력
- 그 외는 무한대(INF)
- 중간 정점
k
를 1개씩 선택 - 모든 출발점
i
, 도착점j
에 대해 distance[i][j] = min(distance[i][j], distance[i][k] + distance[k][j])
- 이를 N번 반복하여 최단 거리 완성
2. 시간 복잡도
- O(N³)
- N: 정점 수
- 3중 for문 → 정점 수가 많을수록 연산량 급증
3. 주로 사용되는 곳
- 모든 노드 간의 거리 계산이 필요한 상황
- 예시:
- 지도 앱의 거리 계산
- 네트워크 통신 지연 시간 측정
- 교통망 분석
4. 예시코드 (Java, 주석 포함)
public class FloydWarshallExample {
static final int INF = 99999999; // 도달 불가능을 나타내는 큰 수
public static void main(String[] args) {
// 입력 그래프: i에서 j로 가는 초기 비용
int[][] graph = {
{0, 4, INF, 6},
{3, 0, 7, INF},
{5, INF, 0, 4},
{INF, 2, INF, 0}
};
int n = graph.length; // 정점 개수
int[][] dist = new int[n][n]; // 최단 거리 배열
// 초기 거리 설정
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
dist[i][j] = graph[i][j];
}
}
// 플로이드-워셜 알고리즘 실행
for (int k = 0; k < n; k++) { // 중간 정점
for (int i = 0; i < n; i++) { // 출발 정점
for (int j = 0; j < n; j++) { // 도착 정점
// i → k → j 경로가 더 짧은 경우 갱신
if (dist[i][k] + dist[k][j] < dist[i][j]) {
dist[i][j] = dist[i][k] + dist[k][j];
}
}
}
}
// 최단 거리 출력
System.out.println("최단 거리 결과:");
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (dist[i][j] == INF) {
System.out.print("INF ");
} else {
System.out.print(dist[i][j] + " ");
}
}
System.out.println();
}
}
}
출력 결과
최단 거리 결과:
0 4 11 6
3 0 7 9
5 7 0 4
5 2 9 0
5. 장점과 단점
✅ 장점
- 모든 정점 쌍의 최단 거리를 한 번에 계산
- 음의 가중치 허용
- 구현이 간단하고 직관적
❌ 단점
- 시간 복잡도 O(N³) → 대규모 그래프에 비효율적
- 음의 사이클 존재 시 잘못된 결과 출력
Share article