Programming/Algorithm

[Algorithm] 플로이드 워셜 알고리즘

당닝 2021. 8. 21. 18:42
728x90

플로이드 워셜 알고리즘

: 모든 지점에서 다른 모든 지점까지의 최단 경로를 모두 구해야 하는 경우에 사용하는 알고리즘

 

- 모든 노드에 대하여 다른 모든 노드로가는 최단 거리 정보를 담아야 하기 때문에 2차원 리스트에 '최단 거리' 정보를 저장함 => N번의 단계에서 매번 O(N^2)의 시간이 소요됨.

 

- 각 단계에서는 해당 노드를 거쳐가는 경우를 고려함.

   ex) 1번 노드에 대해 확인할 때: A -> 1번 노드 -> B로 가는 비용 확인한 후 최단 거리 갱신

  => O(N^3)

 

- 다이나믹 프로그래밍

    점화식: Dab = min (Dab, Dak+Dkb)

              (Dab = a에서 b로 가는 최단 거리)

 

 

출발|도착 1번 2번 3번 4번
1번 0 4 무한 6
2번 3 0 7 무한
3번 5 무한 0 4
4번 무한 무한 2 0

[Step0]

이런 그래프가 있을때, 다음처럼 초기 테이블을 설정할 수 있다.

 

[Step1]

1번 노드를 거쳐 가는 경우를 고려한다.

D23 = min (D23, D21 + D13)

D24 = min (D24, D21 + D14)

D32 = min (D32, D31 + D12)

D34 = min (D34, D31 + D14)

D42 = min (D42, D41 + D12)

D43 = min (D43, D41 + D13)

0 4 무한 6
3 0                                    
5                   0                  
무한                                     0

 

[Step2]

2번 노드를 거쳐 가는 경우를 고려한다.

.

.

.

 

[Step4]

4번 노드를 거쳐 가는 경우를 고려한다.

 

# 플로이드 워셜 알고리즘 (O(N^3))

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] == INF:
              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
'''
728x90