Table of Contents
이 웹 사이트는 귀하가 웹 사이트를 탐색하는 동안 귀하의 경험을 향상시키기 위해 쿠키를 사용합니다. 이 쿠키들 중에서 필요에 따라 분류 된 쿠키는 웹 사이트의 기본적인 기능을 수행하는 데 필수적이므로 브라우저에 저장됩니다. 또한이 웹 사이트의 사용 방식을 분석하고 이해하는 데 도움이되는 제 3 자 쿠키를 사용합니다. 이 쿠키는 귀하의 동의하에 만 브라우저에 저장됩니다. 이러한 쿠키를 거부 할 수도 있습니다. 이러한 쿠키 중 일부를 선택 해제하면 검색 환경에 영향을 미칠 수 있습니다.
Bellman-Ford 알고리즘이 어떻게 작동합니까?
이 알고리즘은 가장자리의 원칙에 따라 각 베텍스에 가장 짧은 거리의 견적을 개선합니다. 소스와 인피니티의 초기 거리로 시작하면 그래프에서 모든 가장자리를 ]|V| − 1]배로 처리합니다. (이 경우 |V|가 vertices의 숫자입니다). 이 패스를 지나면 최종 검사는 1V에서 가장 낮은 1V에서 어떤 부정적인 무게주기가 존재한다는 것을 식별합니다. 1V|V|V|가 합리적으로 가장 긴 주기를 제외하고는 1V|V|가 가장 긴 주기를 포함합니다.
Edge Relaxation의 주요 개념
Relaxation은 알려진 vertex 거리가 가장자리를 가로 질러 개선 할 수 있는지 테스트의 작업입니다. 각 가장자리 (u, v)의 무게 w, 알고리즘 검사 :
if distance[u] + w < distance[v]:
distance[v] = distance[u] + w
불평이 붙으면, vertex v에 거리가 업데이트됩니다. 이 간단한 체크, 반복 된 체계적으로, 필요한 침전 후 보증, 거리는 진정한 짧은 경로를 반영합니다. - 제공된 부정적인 사이클은 소스에서 눈에 띄지 않습니다.
Step-by-Step 구현 가이드
Bellman-Ford를 구현하는 것은 직선 구조를 따릅니다. 아래는 자신의 그래프 표현에 적응할 수있는 샘플 파이썬 코드와 상세한 연습입니다.
데이터 구조 및 초기화
각 vertex 맵을 리스트로(neighbor, weight)의 튜플스(eeighbor)를 사용하여 그래프를 나타냅니다. 0으로 설정된 소스와 다른 모든 정수로 거리를 사전 설정합니다. 선택적으로, 사전 임의 사전은 경로의 경로를 추적할 수 있습니다.
def bellman_ford(graph, source):
# Step 1: Initialize distances
distance = {vertex: float('inf') for vertex in graph}
distance[source] = 0
predecessor = {vertex: None for vertex in graph}
가장자리 Relaxation 반복
실시 |V| − 1개의 이탈은 모든 가장자리에 걸쳐 있습니다. 각 이탈에서는 각 베텍스와 그 인접한 가장자리를 통해 이완 상태를 적용합니다.
# Step 2: Relax all edges |V| - 1 times
for _ in range(len(graph) - 1):
for u in graph:
for v, weight in graph[u]:
if distance[u] + weight < distance[v]:
distance[v] = distance[u] + weight
predecessor[v] = u
부정 주기 탐지
주요 이완 단계 후, 모든 가장자리에 더 많은 패스를 수행. 어떤 거리가 여전히 향상 될 수 있다면, 부정적인 무게 사이클 소스에서 도달 할 수 있으며, 알고리즘은 예외를 제기하거나 오류 표시기를 반환해야합니다.
# Step 3: Check for negative-weight cycles
for u in graph:
for v, weight in graph[u]:
if distance[u] + weight < distance[v]:
raise ValueError("Graph contains a negative-weight cycle")
return distance, predecessor
완료 예
5개의 vertices와 가장자리를 가진 도표를 고려하십시오 부정적인 무게를 포함하는. 뒤에 오는 시험은 알고리즘의 행동을 보여줍니다.
graph = {
'A': [('B', 4), ('C', 2)],
'B': [('C', 3), ('D', 2), ('E', 3)],
'C': [('B', 1), ('D', 4), ('E', 5)],
'D': [],
'E': [('D', -5)]
}
try:
dist, pred = bellman_ford(graph, 'A')
print("Distances:", dist)
except ValueError as e:
print(e)
출력은 vertex A에서 다른 모든 다른 사람에 가장 짧은 거리를 표시하거나 부정적인 주기가 존재하는 경우에 오류를 제기합니다.
공정성 분석
Bellman-Ford는 O(|V| *|E|) 시간 - vertices의 수와 가장자리의 수의 제품. 이것은 Dijkstra의 O(|E|+|V|LOG|V|)보다 훨씬 느리지만, 부정적인 무게를 거래할 수 있는 능력은 O(|V|V|)입니다. 공간 복합성은 O(|V)와 사전 저장 거리의 거리와 사전 저장 거리의 저장 거리입니다.
최적화 및 Variants
몇 가지 개선은 연습에서 실행 시간을 줄일 수 있습니다 :
- Early termination: 각 풀 에지 이완 패스 후, 어떤 거리가 업데이트되었는지 추적합니다. 업데이트가 발생하지 않으면 알고리즘이 융합되고 초기 중지될 수 있습니다.
- Queue-based (SPFA): 매번 편안한 모든 가장자리 대신, 거리가 변경되는 vertices의 큐를 유지. 이것은 가장 짧은 경로 패스너 Algorithm (SPFA)로 알려져 있지만 최악의 케이스 복잡성은 O(|V||||E|) 남아 있습니다.
- Bidirectional Bellman-Ford: 특정 그래프 구조에 대한, 두 개의 동시 이완을 실행 (앞으로 뒤로) 더 빨리 융합 할 수 있습니다.
이 변형에도 불구하고 고전 Bellman-Ford는 일반적인 용도에 가장 똑똑똑하고 신뢰할 수 있습니다.
Dijkstra의 Algorithm과 비교
두 알고리즘은 단일 소스의 가장 짧은 경로 문제를 해결하지만, 해당 응용 프로그램은 다음과 같습니다.
| Feature | Bellman-Ford | Dijkstra |
|---|---|---|
| Negative weights | Supported | Not supported (can produce incorrect results) |
| Negative cycle detection | Yes | No |
| Time complexity | O(|V| * |E|) | O(|E| + |V| log |V|) with binary heap |
| Graph type | Directed or undirected | Generally directed |
| Use case | General shortest paths, arbitrage, constraint propagation | Positive-weight networks like road maps |
Bellman-Ford의 응용
알고리즘의 부정적인 가장자리와 작동 능력과 사이클을 감지하는 것은 전통적인 Dijkstra가 실패 한 필드에서 비유 할 수 있습니다.
네트워크 라우팅 프로토콜
Routing Information Protocol (RIP) - 거리-Vctor routing protocol - 라우터 사이의 최상의 경로를 계산하는 Bellman-Ford의 변형을 사용합니다. 라우터는 주기적으로 거리 테이블을 교환하고 routing 정보를 업데이트하기 위해 Bellman-Ford 방정식을 적용합니다. Bellman-Ford의 융합 메커니즘을 통해 링크 실패와 비용 변경을 처리하는 용량은 강력한 인터넷 routing에 필수적입니다.
금융 Arbitrage 탐지
거래에서, 환율 그래프의 부정적인 사이클은 arbitrage 기회를 의미한다. 각각은 버텍스로 통화를 대표하고 각 교환 쌍은 환율의 부정적인 로그 다람쥐와 동일하게 무게와 가장자리로. 모든 시작 통화에서 Bellman-Ford 실행은 주기가 순이익 (정상 총 무게)을 산출하는 경우 밝혀. 이것은 고주파 거래 시스템에 실제 응용 프로그램이 있습니다.
제약 및 차이점 제약
스케줄링 및 선형 프로그래밍의 많은 문제는 ]] 형태 x j − x i ≤ w의 형태 x j −의 ]의 차이 제약 시스템. 각 변수가 vertex이고 각 제약이 있는 그래프를 만드는 것은 벨만 포드를 사용하여 가장 짧은 경로를 찾는 가장자리 i → j입니다. 알고리즘은 또한 부정적인 사이클을 통해 의도적 제약을 감지합니다.
운송 및 물류
네트워크의 경로 계획은 Bellman-Ford에서 부정적인 (예, 특정 경로에 대한 하위) 혜택을 가질 수 있습니다. 또한 minimum 비용 흐름] 및 ]의 처리 짧은 경로] 작업 연구의 방법.
In-Depth: 부정 주기 탐지 및 취급
부정적인 무게 주기는 총 무게가 0 이하인 주기입니다. 그런 주기가 근원에서 도달할 수 있는 경우에, 가장 짧은 경로는 당신이 길 길이를 감소시키기 위하여 무한하게 주기를 반전할 수 있기 때문에 정의되지 않습니다. Bellman-Ford의 마지막 통행은 특별히 추가 이완이 가능할지도 모르다지 검출합니다. 부정적인 주기가 발견될 때, 전형적인 회복 전략은 다음을 포함합니다:
- 오류 또는 특수 값 (예 :, - 모든 vertices에 대한 무한)을 반환합니다.
- 전임자 배열을 사용하여 사이클에 속한 vertices를 식별합니다.
- Bellman-Ford를 다시 적용하면 문제의 가장자리를 제외하면 비즈니스 논리가 허용됩니다.
알고리즘 경쟁에서 디자이너는 종종 "negative Cycle이 존재"를보고 더 계산을 피합니다.
Bellman-Ford 구현을위한 실용적인 팁
생산 또는 경쟁력있는 프로그래밍 환경에서 Bellman-Ford를 코딩 할 때 이러한 모범 사례를 염두에두고 있습니다.
- ]주의와 인피니티 사용:] Python에서, 잘 작동하지만, 기본적으로 입력된 언어에서, 큰 숫자는 같은 일반적이다. 인피니티에 무게를 추가하는 것은 과잉하지 않는다 (추가하기 전에 명시된 체크를 사용).
- ]지구 그래프를 지시:] Bellman-Ford는 지시한 도표에 기본적으로 작동합니다. 간접한 도표를 위해, 2개의 지시한 가장자리를 가진 각 가장자리를 대체하거나 이완 반복에서 비대칭으로 취급하십시오.
- ]평면 목록의 상점 가장자리: dense graphs를 위해, adjacency 명부를 통해 모든 가장자리에 격리는 안 반복 머리 위 때문에 계수일 수 있습니다. (u, v, 무게) 트리플의 세계적인 명부는 수시로 더 나은 실행합니다.
- 코너 케이스 테스트: Graphs with a single vertex, Multiple Zero-weight cycle, or the splited negative cycle outside the source’s 도달은 모두 확인되어야 합니다.
관련 기사
Bellman-Ford 알고리즘은 부정적인 가장자리를 포함하는 무게를 다는 그래프에서 가장 짧은 경로 문제를 해결하기위한 인디펜스 가능한 도구입니다. 그것의 단순성, 부정적인 사이클을 감지 할 수있는 능력과 결합하여 이론적 인 컴퓨터 과학과 실제 공학의 요소가됩니다. 구현을 마스터하고 양도에 대한 이해 - 초기 종료 후의 병력에서 응용 프로그램에 대한 인식 - 당신은 신뢰와 벨만-Ford를 배포 할 수 있습니다. [G] [G] [G]] [G] [G]] [G]] [G]] [G]] [G]] [G]] [G]]] [G]] [G]] [G]]] [G] []]] [G] []]] [] []]] []] [] [] [] []] [] [] [] [] [] [] [] []] [] [] []]]] [] [] [] [] [] [] [] [] [] [] [] []] [] [] []]]]] []]]]]] []]]]]]