Algorithm/Python

Python - 플로이드 워셜 알고리즘 (Floyd-Warshall)

yxemsy 2022. 2. 26. 20:08

- 플로이드 워셜 알고리즘

1. 모든 노드에서 다른 모든 노드까지의 최단 경로를 모두 계산한다.

2. 플로이드 워셜 알고리즘은 단계별로 거쳐가는 노드를 기준으로 알고리즘을 수행한다.
  * 다만, 매 단계마다 방문하지 않은 노드 중에 최단 거리를 갖는 노드를 찾는 과정이 필요하지 않다.

3. 2차원 테이블에 최단 거리 정보를 저장한다.

4. 다이나믹 프로그래밍 유형이다.

 

  • 각 단계마다 특정한 노드 k를 거쳐 가는 경우를 확인한다.

예를 들어, a에서 b로 가는 최단 거리보다 a에서 k를 거쳐 b로 가는 거리가 더 짧은지 검사한다.

점화식은 다음과 같다.

a→b로 가는 거리 = (a→b로 가는 거리의 값)과, (a→k 값에 k→b를 더한 값) 중 작은 값이 된다. 

만약 a→b로 가는 간선이 없다면, 그건 무한으로 처리한다.

 

코드로 구현하면 다음과 같다.

infinite = int(1e9) # 무한을 의미하는 값으며 10억 설정

n = int(input()) # 노드의 개수 입력
m = int(input()) # 간선의 개수 입력

# 2차원 리스트 만들고, 무한으로 초기화
graph =  [ [infinite] * (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):
    	# 도달이 불가능하면 무한 이라고 출력
        if graph[a][b] == infinite:
        	print("무한", end=' ')
        else:
        	print(graph[a][b], end=' ')
    print()

 

 

참고: https://youtu.be/acqm9mM1P6o