본 내용은 '이것이 취업을 위한 코딩테스트다 with 파이썬' 책을 기반으로 포스팅 하였습니다.
플로이드 워셜 알고리즘
모든 노드에서 다른 모든 노드까지의 최단 경로를 모드 계산하는 알고리즘이다.
다익스트라 알고리즘과 마찬가지로 단계별로 거쳐 가는 노드를 기준으로 알고리즘을 수행한다.
다만 매 단계마다 방문하지 않은 노드 중에 최단 거리를 갖는 노드를 찾는 과정이 필요하지 않다.
2차원 테이블에 최단 거리 정보를 저장한다.
각 단계마다 특정한 노드 k를 거쳐 가는 경우를 확인한다.
a에서 b로 가는 최단거리보다 a에서 k를 거쳐 b로 가는 거리가 더 짧은지 검사한다.
다이나믹 프로그래밍 유형에 속한다.
플로이드 워셜 알고리즘 동작 과정
step1 1번 노드를 거쳐 가는 경우를 고려하여 테이블을 갱신한다.
step2 2번 노드를 거쳐 가는 경우를 고려하여 테이블을 갱신한다.
step3 3번 노드를 거쳐 가는 경우를 고려하여 테이블을 갱신한다.
step4 4번 노드를 거쳐 가는 경우를 고려하여 테이블을 갱신한다.
플로워셜 알고리즘 소스코드
// 노드의 개수 입력받기
let n = Int(readLine()!)!
// 간선의 개수 입력받기
let m = Int(readLine()!)!
// 2차원 리스트에 모든 값을 9999999999(무한)으로 초기화
var graph = Array(repeating: Array(repeating: [9999999999], count: n+1), count: n+1)
// 자기 자신에서 자기 자신으로 가는 비용 0으로 초기화
for i in 0...n {
for j in 0...n {
if i == j {
graph[i][j] = [0]
}
}
}
// 각 간선에 대한 정보를 입력받고 초기화
// input[0] = 출발노드
// input[1] = 도착노드
// input[2] = 비용
for _ in 1...m {
let input = readLine()!.components(separatedBy: " ").map({Int($0)!})
graph[input[0]][input[1]] = [input[2]]
}
// 점화식에 따라 플로이드 워셜 알고리즘 수행
// 각각의 노드를 거쳐가는 경우를 계산해 a에서 b로 가는 비용이 더 작을때 값 갱신
for k in 1...n {
for a in 1...n {
for b in 1...n {
graph[a][b] = [min(graph[a][b].first!, graph[a][k].first! + graph[k][b].first!)]
}
}
}
// 결과 출력
for i in graph {
print(i)
}
/*
[[0], [9999999999], [9999999999], [9999999999], [9999999999]]
[[9999999999], [0], [4], [8], [6]]
[[9999999999], [3], [0], [7], [9]]
[[9999999999], [5], [9], [0], [4]]
[[9999999999], [7], [11], [2], [0]]
*/
플로이드 워셜 알고리즘 성능 분석 1. 노드의 개수가 N개일 때 알고리즘상으로 N번의 단계를 수행한다. 2. 각 단계마다 O(N^2)의 연산을 통해 현재 노드를 거쳐 가는 모든 경로를 고려한다. 3. 따라서 플로이드 워셜 알고리즘의 총 시간복잡도는 O(N^3)이다.