📚벨만-포드 알고리듬

단일 출발점 최단 경로를 구할 수 있는 알고리듬이다. 다익스트라 알고리듬과는 다르게 벨만-포드 알고리듬은 음의 가중치를 갖는 간선이 존재하는 그래프에 대해서도 단일 출발점 최단 경로를 구할 수 있다.(단, 음의 사이클이 없어야 한다.)


📄수행과정

  • 초기화: 출발점 s의 거리는 0, 나머지 모든 정점 v들의 거리는 ∞으로 초기화

  • 간선을 1 개부터 그래프 간선의 개수 - 1(n - 1)개 까지 사용하는 최단 경로 구함: 모든 간선을 한 번씩 조사하면서 거리값 조정 여부를 결정.

d[v] <- min{기존거리, 간선 <u, v>를 지나는 경우의 거리}: 기존거리와 해당 간선을 지남으로써 결정되는 거리 중 작은 값으로 거리 값을 조정.

실제로 각 단계에서 모든 간선을 조사할 필요 없이 이전 단계에서 거리값이 조정된 정점에 부수된 간선만 조사하여 효율적인 처리 가능.


📄성능과 특징

  • 음의 가중치를 갖는 간선이 있는 경우
    • 다익스트라 알고리듬 적용 불가
    • 벨만-포드 알고리듬 적용 가능(음의 사이클 존재하면 적용 불가)
  • 음의 가중치를 갖는 간선이 없는 경우
    • 다익스크라 알고리듬 -> O(|V|+|E|)
    • 벨만-포드 알고리듬 -> O(|V||E|)



📚플로이드 알고리듬

모든 쌍 최단 경로 알고리듬(출발점이 정해져 있지 않음. 임의의 두 정점 간 최단 경로 구하는 알고리듬)

  • 경로의 길이가 음의 사이클이 존재하지 않는다고 가정

  • 동적 프로그래밍 기법 적용

  • 경유할 수 있는 정점의 범위가 1인 경로부터 최대 정점 개수(n)인 경로까지 하나씩 정점의 범위를 늘려 모든 정점 간의 최단 경로를 한꺼번에 구함


📄인접 행렬 표현 활용

\[D^{(k)} = (d_{ij}^{(k)})\]

정점 번호가 k 이하인 정점만을 경유하는 정점 i에서 j까지의 최단 경로의 길이

D(0)부터 D(n)까지 구해서 최종 결과를 구한다.

D(0)는 정점 i에서 정점 j까지 아무것도 거치지 않는 최단 경로 길이를 의미한다.(그래프를 인접행렬로 표현 -> 초기화)

D(0)부터 D(n)까지 구할 때 점화식의 형태로 최종 결과를 구한다.

\[d_{ij}^{(k)} = min(d_{ij}^{(k - 1)}, d_{ik}^{(k - 1)} + d_{kj}^{(k - 1)})\]

기존 거리(정점 i에서 정점 j로 바로 가는 거리)와 정점 k를 경유하는 경우의 거리(i -> k -> j)를 비교하여 작은 값을 선택한다.


📄성능과 특징

  • 동적 프로그래밍 방법을 적용한 알고리듬

  • 다익스트라 알고리듬으로 모든 쌍 최단 경로를 구할 수 있음
    • 각 정점에 대해 반복적으로 적용 -> O(|V|3)
    • 하지만, 플로이드 알고리듬이 더 간단하므로 빠르게 수행 가능
  • P[1..n][1..n]를 활용하면 최단 경로 자체를 구할 수 있음
    • P[i][j] = k(기존 거리보다 정점 k를 경유하는 경우의 거리가 작을 때)



📚포드-풀커슨 알고리듬

📄네트워크 플로 문제

  • 주어진 네트워크에 대해 플로(flow)를 최대로 하는 값을 찾는 문제
    • 소스에서 싱크로 보낼 수 있는 플로 값을 최대로 하는 문제 -> 최대 플로 문제
  • 네트워크 N = (V, E, s, t, c)
    • 방향 그래프 G=(V,E)
    • s: 소스(시작점, 진입차수가 0인 정점). 들어오는 간선이 없는 정점
    • t: 싱크(도착점, 진출차수가 0인 정점). 나가는 간선이 없는 정점
    • c: 간선의 가중치 -> 간선의 용량(capacity)
      • c(u, v) -> 간선 <u, v>를 통해 보낼 수 있는 최대의 양/값


📝플로 f: E -> R+

  • 간선의 용량 중에서 실제 사용하고 있는 양/값
  • 용량 제약 조건: 모든 <u, v>∈E에 대해 0 <= f(u,v) <= c<u,v>
    • 임의의 간선의 플로는 항상 0보다 크거나 같고, 해당 간선의 용량을 초과하지 못함
  • 플로 보존 제약 조건: 모든 v∈V-{s, t}에 대하여 SUM f(u, v) = SUM f(v, w)
    • 소스/싱크를 제외한 모든 정점에 대해 어떤 정점으로 들어오는 양과 나가는 양은 동일
  • 플로 값(총 플로) F
    • 소스에서 나가는 플로의 합, 싱크로 들어오는 플로의 합


📄포드-풀커슨 알고리듬

  • 최초로 제시된 가장 기초적인 네트워크 플로 해결방법
    • 단순히 플로 값을 증가시킬 수 있는 모든 경우의 수를 탐색해서 적용
    • 종료가 보장되지 않음 -> 에드몬즈-카프 알고리듬으로 발전
  • 모든 간선의 플로를 0으로 둔 상태에서 시작해서 증가 경로가 더 이상 존재하지 않을 때 까지 반복적으로 경로를 찾아서 최대 플로 값을 구하는 방법


📝증가 경로

  • 소스에서 싱크까지 더 많은 플로를 보낼 수 있는 경로
  • 경로상의 간선은 네트워크 N의 간선 방향과 일치하지 않을 수 있음
    • 순방향 간선 -> 간선 <u, v>가 N의 간선과 방향과 같은 경우
    • 역방향 간선 -> 간선 <u, v>가 N의 간선과 방향과 다른 경우
      • <v, u>∈E와 방향이 반대인 간선 -> <u, v>∉E인 가상의 간선
      • c(u, v) = 0, f(u, v) = -f(v, u)
      • 남아 있는 모든 가능한 경로를 더 찾아낼 수 있게 하는 포드-풀커슨 방법의 핵심


📝잔여 용량 r(u, v)

  • 간선 <u, v>에서 추가로 플로를 증가시킬 수 있는 여유 용량
    • 순방향 간선 -> r(u, v) = c(u, v) - f(u, v) -> 증가시킬 수 있는 양/값
    • 역방향 간선 -> 원래 간선에 부영된 플로를 줄일 수 있는 양/값


📝증가 경로의 여유량

  • 경로에 포함된 모든 간선의 잔여 용량 중 최소값
    • 해당 경로를 사용해서 증가시킬 수 있는 플로 값


📝알고리듬

  • 초기화: 간선의 플로/ 간선의 용량(예: 0/8)
  • 증가 경로를 찾고 해당 경로의 여유량으로 모든 간선의 플로를 조정하는 과정을 반복


📄성능과 특징

  • 시간 복잡도: O(|E| F)
  • 간선의 용량에 무리수가 사용되면 알고리듬이 종료하지 않을 수 있다
  • 용량이 정수라고 해도 M이 매우 큰 값이라면 비효율적인 결과를 보인다
  • 증가 경로 선택은 DFS 또는 BFS 적용
    • 포드-풀커슨 알고리듬 -> 기본적으로 DFS를 적용하여 증가 경로 선택
    • 에드몬즈-카프 알고리듬 -> BFS 적용, O(|V||E|2), 포드-풀커슨 문제 해결
  • 커트
    • 소스 s와 싱크 t가 서로 다른 집합에 속하도록 정점의 집합 V를 두 개로 나눈다. 소스는 집합 S에 싱크는 집합 T에 속하게 됨
    • 커트 -> (S; T) ∪ (T; S)
    • (S; T): S의 정점에서 T의 정점으로 향하는 간선의 집합
    • 커트의 용량(플로)은 소스에서 싱크로의 최대 플로와 같다.



Leave a comment