플로이드-워셜 알고리즘(Floyd-Warshall Algorithm)은 그래프에서 모든 꼭짓점 사이의 최단 경로의 거리를 구하는 알고리즘이다. 음수 가중치를 갖는 간선도 순환만 없다면 잘 처리된다. 제일 바깥쪽 반복문은 거쳐가는 꼭짓점이고, 두 번째 반복문은 출발하는 꼭짓점, 세 번째 반복문은 도착하는 꼭짓점이다. 이 알고리즘은 플로이드 알고리즘이라고도 알려져 있다.
출처 : 위키백과
모든 정점들 사이의 최단거리를 구하는 알고리즘이므로, 시간이 많이 소요된다는 단점이 있다.
예)
초기 배열은 자기 자신은 0, 나머지는 무한대로 초기화한다.
각 간선의 정보를 배열에 설정한다.
경유지를 탐색하여, 더 짧은 경로가 존재하면 업데이트한다.
(0 → 3 의 경우 거리가 4이나, 0 → 1 → 3 으로 1을 거쳐가는 경우 거리가 1 + 2 = 3 으로 더 짧다.)
소스코드 (입력하는 과정 생략)
import java.io.*; public class Main { public static final int INF = 10000; public static void main(String[] args) { int[][] d = new int[][]{{0, 1, INF, 4}, {INF, 0, 3, 2}, {1, INF, 0, 5}, {INF, INF, INF, 0}}; // 경유지 for (int k = 0; k < 4; k++) { for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { if (d[i][j] > d[i][k] + d[k][j]) { d[i][j] = d[i][k] + d[k][j]; } } } } for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { if (d[i][j] == INF) System.out.printf("%4s", "INF"); else System.out.printf("%4d", d[i][j]); } System.out.println(); } } }
순서를 몇가지 나열해보면
① k = 0일 때,
i = 0
j = 0 : d[0][0] > d[0][0] + d[0][0]
j = 1 : d[0][1] > d[0][0] + d[0][1]
j = 2 : d[0][2] > d[0][0] + d[0][2]
j = 3 : d[0][3] > d[0][0] + d[0][3]
i = 1
j = 0 : d[1][0] > d[1][0] + d[0][0]
j = 1 : d[1][1] > d[1][0] + d[0][1]
j = 2 : d[1][2] > d[1][0] + d[0][2] ---> [1 → 2]로 가는 거리와, [1 → 0 → 2] 0을 거쳐가는 거리 비교
j = 3 : d[1][3] > d[1][0] + d[0][3]
...
② k = 1일 때,
i = 0
j = 0 : d[0][0] > d[0][1] + d[1][0]
j = 1 : d[0][1] > d[0][1] + d[1][1]
j = 2 : d[0][2] > d[0][1] + d[1][2]
j = 3 : d[0][3] > d[0][1] + d[1][3]
...
이와 같이, 모든 노드 사이의 최단경로를 구한다.
'Algorithm > 개념' 카테고리의 다른 글
[Algorithm] 정렬 - 선택 정렬 (Selection Sort) (0) | 2019.05.23 |
---|---|
[Algorithm] 정렬 - 거품 정렬 (Bubble Sort) (0) | 2019.05.23 |
[Algorithm] 정렬 - 삽입 정렬 (Insertion Sort) (0) | 2019.05.23 |
[Algorithm] 유클리드 호제법 (0) | 2019.05.22 |
[Algorithm] Breadth-first search (너비 우선 탐색) (0) | 2018.05.07 |