[알고리즘] 플로이드 워셜 알고리즘(Floyd-Warshall Algorithm)
이것이 취업을 위한 코딩 테스트다. with 파이썬
책을 참고하여 정리한 내용입니다.
✅ 플로이드 워셜 알고리즘
플로이드 워셜 알고리즘(Floyd-Warshall Algorithm)은 '모든 지점에서 다른 모든 지점까지의 최단 경로를 모두 구해야 하는 경우'에 사용할 수 있는 알고리즘이다. 해당 알고리즘은 노드의 개수가 $N$개 일 때 알고리즘상으로 N번의 단계를 수행하며, 단계마다 $O(N^2)$의 연산을 통해 ‘현재 노드를 거쳐 가는’ 모든 경로를 고려한다. 따라서 플로이드 워셜 알고리즘의 총 시간 복잡도는 $O(N^3)$이다.
플로이드 워셜 알고리즘은 2차원 리스트에 ‘최단 거리’ 정보를 저장하며, ‘점화식에 맞게’ 2차원 리스트를 갱신하기 때문에 다이나믹 프로그래밍으로 볼 수 있다. 점화식은 다음과 같다.
\[D_{ab} = min(D_{ab}, D_{ak} + D_{kb})\]‘a에서 b로 가는 최소 비용’과 ‘a에서 k를 거쳐 b로 가는 비용’ 중 더 작은 값으로 갱신하겠다는 의미이다.
✔️ 플로이드 워셜 알고리즘 소스코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import sys
INF = int(1e9) # 무한을 의미하는 값으로 10억을 설정
# 노드의 개수 및 간선의 개수를 입력받기
n = int(sys.stdin.readline())
m = int(sys.stdin.readline())
# 2차원 리스트(그래프 표현)를 만들고, 모든 값을 무한으로 초기화
graph = [[INF] * (n + 1) for _ in range(n + 1)]
# 자기 자신에서 자기 자신으로 가는 비용은 0으로 초기화
for a in range(1, n + 1):
for b in range(1, n + 1):
if a == b:
graph[a][b] = 0
# 각 간선에 대한 정보를 입력받아, 그 값으로 초기화
for _ in range(m):
# A에서 B로 가는 비용은 C라고 설정
a, b, c = map(int, sys.stdin.readline().split())
graph[a][b] = c
# 점화식에 따라 플로이드 워셜 알고리즘을 수행
for k in range(1, n + 1):
for a in range(1, n + 1):
for b in range(1, n + 1):
graph[a][b] = min(graph[a][b], graph[a][k] + graph[k][b])
This post is licensed under CC BY 4.0 by the author.