[Python] 최단 경로 - 벨만 포드(Bellman-Ford) 알고리즘 구현하기

yunyoung·2021년 4월 22일

벨만 포드 알고리즘은 그래프에서 시작 정점으로부터 다른 정점까지의 최단 경로를 찾기 위한 알고리즘이다. 벨만 포드 알고리즘의 특징은 다음과 같다.

  1. 음수 가중치가 있는 그래프의 시작 정점에서 다른 정점까지의 최단 거리를 구할 수 있다.
  2. 음수 사이클 존재의 여부를 알 수 있다.

음수 사이클 안에서 무한으로 뺑뺑이 도는 경우를 알 수 있는 방법은, 그래프 정점의 개수를 V라고 할 때 인접 간선을 검사하고 거리 값을 갱신하는 과정을 V-1번으로 제한하면 가능해진다. 그래프의 시작 정점에서 특정 정점까지 도달하기 위해 거쳐 가는 최대 간선 수는 V-1개이기 때문에 V번째 간선이 추가되는 순간 사이클이라고 판단할 수 있게 된다.

벨만 포드 알고리즘의 시간 복잡도는 O(VE)이다.

벨만 포드 알고리즘 프로세스

  1. 시작 정점을 결정한다.
  2. 시작 정점에서 각각 다른 정점까지의 거리 값을 무한대로 초기화한다.
    (시작 정점이 a라면, distance[b] = a->b의 거리를 뜻함)
    시작 정점 -> 시작 정점은 0으로 초기화한다.
  3. 현재 정점에서 모든 인접 정점들을 탐색하며, 기존에 저장되어 있는 인접 정점까지의 거리(distance[a])보다 현재 정점을 거쳐 인접 정점에 도달하는 거리가 더 짧을 경우 짧은 거리로 갱신해준다.
  4. 3번의 과정을 V-1번 반복한다.
  5. 위 과정을 모두 마치고 난 후 거리가 갱신되는 경우가 생긴다면 그래프에 음수 사이클이 존재한다는 것이다.


시작점이 1일 때, Dist[1]0으로 놓고 나머지는 무한대로 설정한다.

시작점 1의 인접 정점들을 탐색하며, Dist[노드]에 저장되어 있는 값보다 정점 1을 거쳐 가는 값이 더 작을 경우 그 값으로 업데이트한다. 여기서는 모두 INF 무한대 값보다 작기 때문에 다 업데이트하게 된다.

정점 2의 인접 정점들을 탐색한다. 현재 정점(2)를 거쳐 정점 4로 가는 것이 정점 2를 거치지 않는 것보다 더 비용이 적게 들기 때문에 업데이트해준다.



계속해서 V-1번이 될 때까지 반복해준다. 최종적으로 {0, -4, 5, -5, 1}이 나오게 된다.

음수 사이클

V-1번 반복이 끝난 이후, 한 번 더 위의 과정을 돌려주었을 때 값이 바뀐다면 음수 사이클이 있는 그래프임을 알 수 있다. (distance[a]에 저장되어 있는 값보다 현재 정점을 거쳐 가는 비용이 더 작다고 판별될 경우) 음수 사이클이 존재하는 경우에는 음수 가중치를 계속해서 더해주게 되어 최단 거리를 구할 수 없는 무한 루프에 빠지게 된다.

벨만 포드 구현 코드(Python)

참고 링크

[Algorithm] Bellman-Ford(벨만포드) - 새로비님 블로그

profile
🌈TIL과 개발 노트

0개의 댓글