우노
[Algorithm] 플로이드 워셜(Floyd-Warshall) 알고리즘이란? 본문
플로이드 워셜(Floyd-Warshall) 알고리즘이란?
- 플로이드 워셜 알고리즘은 ‘모든 지점에서 다른 모든 지점까지의 최단 경로를 모두 구해야 하는 경우'에 사용할 수 있는 알고리즘입니다.
- 해당 알고리즘은 매 단계마다 ‘현재 노드를 거쳐 가는 노드'를 기준으로 알고리즘을 수행합니다.
- 노드의 개수가 N개일 때, 알고리즘상으로 N번의 단계를 통해 현재 노드를 선택하며,
- 단계마다 O(N^2)의 연산을 통해 ‘현재 노드를 거쳐 가는' 모든 경로를 고려합니다.
- 따라서, 플로이드 워셜 알고리즘의 총 시간 복잡도는 O(N^3)입니다.
- 해당 알고리즘은 2차원 리스트에 ‘최단 거리' 정보를 저장한다는 특징이 있습니다.
- 모든 노드가 다른 모든 노드로 가는 최단 거리 정보를 담아야 하기 때문입니다.
- 해당 알고리즘은 다이나믹 프로그래밍이라는 특징이 있습니다.
- 노드의 개수가 N이라고 할 때, N번 만큼의 단계를 반복하며
- ‘점화식에 맞게' 2차원 리스트를 갱신합니다.
- 예제
- 예를 들어, 현재 1번 노드를 선택했다면, 1번 노드를 중간에 거쳐 지나가는 모든 경우를 고려하게 됩니다.
- 만약, 최단 거리 테이블에 A번 노드에서 B번 노드로 이동하는 비용이 3으로 기록되어 있을 때,
- A번 노드에서 1번 노드를 거쳐 B번 노드로 이동하는 비용이 2라면,
- A번 노드에서 B번 노드로 이동하는 비용을 2로 갱신하는 방식으로 진행됩니다.
점화식
- D_ab = min(D_ab, D_ak + D_kb)
정리
- 전체적으로 3중 반복문을 이용하며, 위의 점화식에 따라 최단 거리 테이블을 갱신하면 됩니다.
- 위의 점화식은, ‘A에서 B로 가는 최소 비용'과 ‘A에서 K를 거쳐 B로 가는 비용'을 비교하여, 더 작은 값으로 갱신하겠다는 의미입니다.
중요
- 초기 테이블 설정 시, ‘연결되지 않은 간선'에는 임의의 큰 값을 넣습니다.
- 또한, 자기 자신으로 가는 비용은 모두 0으로 초기화합니다.
- 왼쪽 위에서 오른쪽 아래로 내려가는 대각선
- 마지막으로, 현재 노드가 포함된 행과 열은 업데이트되지 않습니다.
- 예를 들어, 현재 노드로 1번 노드가 선택됐을 경우,
- 업데이트 해야하는 값은, 1번 노드를 거쳐가는 간선이므로,
- 2에서 1로 가는 간선 및 1에서 2로 가는 간선과 같이 직접 연결된 간선은 업데이트 되지 않습니다.
동작 과정 예제
예제 코드
INF = int(1e9) # 무한을 의미하는 값으로 10억을 설정
# 노드의 개수 및 간선의 개수를 입력받기
n = int(input())
m = int(input())
# 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, input().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])
# 수행된 결과를 출력
for a in range(1, n + 1):
for b in range(1, n + 1):
# 도달할 수 없는 경우, 무한(INFINITY)이라고 출력
if graph[a][b] == 1e9:
print("INFINITY", end=" ")
# 도달할 수 있는 경우 거리를 출력
else:
print(graph[a][b], end=" ")
print()
입력 및 출력 예시
4
7
1 2 4
1 4 6
2 1 3
2 3 7
3 1 5
3 4 4
4 3 2
0 4 8 6
3 0 7 9
5 9 0 4
7 11 2 0
참고
- 이것이 바로 취업을 위한 코딩테스트다. with Python
- https://www.youtube.com/watch?v=acqm9mM1P6o
'Algorithm > Concept' 카테고리의 다른 글
[Algorithm] 서로소 집합이란? (0) | 2022.07.05 |
---|---|
[Algorithm] 트리와 그래프의 차이 (0) | 2022.07.05 |
[Algorithm] Top-Down, Bottom-Up 이란? (0) | 2022.06.12 |
[Algorithm] 정렬 알고리즘 종류 (0) | 2022.06.06 |
[Algorithm] DFS 와 BFS 문제 구분 방법 (0) | 2022.06.05 |
Comments