플로이드–워셜 알고리즘 (모든 노드 간 최단 경로 구하기)

2025. 4. 21. 23:07·Computer Science
728x90

문제 정의: 출발점이 고정되지 않은 최단경로 탐색

앞선 다익스트라와 벨만-포드는 모두

“특정 시작점에서 다른 모든 노드까지의 거리”를 구하는 알고리즘입니다.

하지만 실전에서는 이런 상황도 자주 생깁니다:

  • A → B 최단거리?
  • 모든 도시 쌍 간의 최소 소요 시간은?
  • 특정 노드에서 어떤 노드로 거쳐 갈 때 경로는 어떤가?

이렇게 모든 정점 쌍 (i, j)에 대해 최단 거리를 구해야 하는 경우,
플로이드–워셜 알고리즘이 가장 효과적입니다.


개념 요약: 경유지를 하나씩 늘려가며 최단 거리 갱신

플로이드–워셜 알고리즘은

"한 노드에서 다른 노드로 갈 때, 어떤 노드를 거치면 더 짧아질 수 있을까?"
를 매 반복마다 전체 쌍에 대해 확인합니다.

이 알고리즘의 핵심은 **DP 테이블(2차원 배열)**을 쓰는 것입니다.


핵심 아이디어:

모든 노드 쌍 (i, j)에 대해,

경유 노드 k를 거쳤을 때
dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j])

즉,

"기존 거리와 k를 경유했을 때 거리 중 더 짧은 쪽으로 갱신"
→ 이 연산을 k = 1부터 n까지 반복합니다.


알고리즘 동작 원리 단계별 설명

초기 세팅

  • 노드 수: n
  • dist[i][j] 테이블을 생성 (초기값: 간선 가중치, 연결 없으면 무한대)
  • 자기 자신 dist[i][i] = 0

3중 반복 구조

for k in range(1, n+1):        # 경유지
    for i in range(1, n+1):    # 출발지
        for j in range(1, n+1):# 도착지
            dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j])

이 구조는 “점진적 최적화”라는 관점에서 이해하면 쉽습니다.

경로가 "점점 똑똑해지는 과정"이라고 보면 됩니다.

 


Python 구현 예제

def floyd_warshall(n, edges):
    INF = float('inf')
    dist = [[INF] * (n + 1) for _ in range(n + 1)]

    for i in range(1, n + 1):
        dist[i][i] = 0

    for u, v, w in edges:
        dist[u][v] = min(dist[u][v], w)  # 중복 간선 고려

    for k in range(1, n + 1):
        for i in range(1, n + 1):
            for j in range(1, n + 1):
                if dist[i][k] + dist[k][j] < dist[i][j]:
                    dist[i][j] = dist[i][k] + dist[k][j]

    return dist

 

edges = [
    (1, 2, 4),
    (1, 3, 2),
    (2, 3, 5),
    (3, 2, 1),
    (2, 4, 2),
    (3, 4, 3)
]

간선 입력 예


시간복잡도

단계 복잡도
테이블 초기화 O(V²)
3중 반복문 O(V³)

 

모든 정점 쌍에 대해 계산하므로
노드 수가 100 이하일 때 실용적,
→ 매우 작은 그래프에서는 가장 단순하면서도 강력한 최단경로 알고리즘


음수 간선 허용? 사이클은?

항목 지원 여부
음수 가중치 가능
음수 사이클 탐지 가능 (자기 자신으로 돌아오는 경우 확인)

 

 

다익스트라 / 벨만–포드 / 플로이드–워셜 비교

항목 다익스트라 벨만–포드 플로이드–워셜
지원 음수 X 음수 O 음수 O
사이클 탐지 X O O
시간복잡도 O(E log V) O(VE) O(V³)
목적 한 지점 → 모든 지점 한 지점 → 모든 지점 (음수 포함) 모든 지점 쌍 간 최단 거리
 

요약

  • 플로이드–워셜은 그래프 내 모든 노드 쌍에 대한 최단 거리를 계산한다.
  • 간단하지만 강력한 알고리즘으로, DP적 사고가 핵심
  • 시간복잡도는 O(V³)로 다소 무겁지만, 작은 그래프에서는 매우 적합
  • 음수 간선/음수 사이클까지 안전하게 처리 가능
  • 전체 경로 테이블이 필요할 때는 이게 최적의 선택!
728x90
반응형
저작자표시 비영리 변경금지 (새창열림)

'Computer Science' 카테고리의 다른 글

LCS(최장 공통 부분 수열 & 문자열 DP 문제)  (0) 2025.04.22
최소 신장 트리(MST) (Kruskal vs Prim 알고리즘 비교)  (0) 2025.04.22
벨만-포드 알고리즘 (Dijkstra를 넘어서는 그래프 알고리즘)  (1) 2025.04.21
위상 정렬 – 순서를 정해야 할 때 사용하는 그래프 알고리즘  (0) 2025.04.18
백트래킹(Backtracking) - 조합, 순열, N-Queen  (0) 2025.04.18
'Computer Science' 카테고리의 다른 글
  • LCS(최장 공통 부분 수열 & 문자열 DP 문제)
  • 최소 신장 트리(MST) (Kruskal vs Prim 알고리즘 비교)
  • 벨만-포드 알고리즘 (Dijkstra를 넘어서는 그래프 알고리즘)
  • 위상 정렬 – 순서를 정해야 할 때 사용하는 그래프 알고리즘
Balang
Balang
음악 전공생의 개발일지
  • Balang
    Balang
    Balang
  • 전체
    오늘
    어제
  • 반응형
    • All Post (147)
      • python (45)
        • selenium (4)
        • algorithm (9)
        • Django (6)
        • Pandas | Numpy (22)
      • SQL (9)
      • Data Engineer (29)
      • Data Scientist (3)
      • Data Analysis (9)
      • Computer Science (35)
      • Why? (15)
      • 마음가짐 (2)
  • 인기 글

  • 최근 댓글

  • 최근 글

  • 250x250
  • hELLO· Designed By정상우.v4.10.3
Balang
플로이드–워셜 알고리즘 (모든 노드 간 최단 경로 구하기)
상단으로

티스토리툴바