feat:增加部分图论算法

This commit is contained in:
ViperEkura 2026-04-08 23:45:43 +08:00
parent 1db70cdf59
commit 27a3402d1c
1 changed files with 207 additions and 1 deletions

View File

@ -12,4 +12,210 @@
### Bellman-Ford算法 ### Bellman-Ford算法
### Bellman-Ford算法 #### 数学公式
对于图 $G=(V,E)$Bellman-Ford算法通过迭代松弛更新每个顶点的最短路径估计
$$d(v) = \min\{d(u) + w(u,v) | (u,v) \in E\}$$
其中:
- $d(v)$ 是从源顶点到顶点 $v$ 的最短路径估计
- $w(u,v)$ 是边 $(u,v)$ 的权重
- 迭代次数最多为 $|V|-1$ 次
#### Python实现
```python
def bellman_ford(graph, source):
"""
Bellman-Ford算法求单源最短路径
参数:
graph: 邻接表表示的图,格式 {u: [(v, w), ...]}
source: 源顶点
返回:
distances: 各顶点到源顶点的最短距离
"""
# 初始化距离
distances = {v: float('inf') for v in graph}
distances[source] = 0
# 获取所有顶点
vertices = list(graph.keys())
# 最多进行 |V|-1 次迭代
for _ in range(len(vertices) - 1):
# 对每条边进行松弛操作
for u in graph:
for v, w in graph[u]:
if distances[u] != float('inf') and distances[u] + w < distances[v]:
distances[v] = distances[u] + w
# 检测负权重环
for u in graph:
for v, w in graph[u]:
if distances[u] != float('inf') and distances[u] + w < distances[v]:
raise ValueError("图中存在负权重环")
return distances
# 示例使用
if __name__ == "__main__":
# 构建图 (邻接表)
graph = {
'A': [('B', 4), ('C', 2)],
'B': [('C', 3), ('D', 2), ('E', 3)],
'C': [('B', 1), ('D', 4)],
'D': [('E', -5)], # 负权重边
'E': []
}
try:
distances = bellman_ford(graph, 'A')
print("Bellman-Ford 结果:", distances)
except ValueError as e:
print(e)
```
---
## 常用算法Python实现
### 1. Dijkstra算法
#### 数学公式
Dijkstra算法维护一个优先队列每次选取具有最小距离估计的顶点
$$d(v) = \min_{u \in S} \{ d(u) + w(u,v) \}$$
其中 $S$ 是已确定最短路径的顶点集合。
#### Python实现
```python
import heapq
def dijkstra(graph, source):
"""
Dijkstra算法求单源最短路径
参数:
graph: 邻接表表示的图,格式 {u: [(v, w), ...]}
source: 源顶点
返回:
distances: 各顶点到源顶点的最短距离
"""
# 初始化距离
distances = {v: float('inf') for v in graph}
distances[source] = 0
# 优先队列: (距离, 顶点)
pq = [(0, source)]
visited = set()
while pq:
# 取出最小距离的顶点
current_dist, u = heapq.heappop(pq)
# 如果已访问则跳过
if u in visited:
continue
visited.add(u)
# 更新邻接顶点的距离
for v, w in graph.get(u, []):
if v not in visited and current_dist + w < distances[v]:
distances[v] = current_dist + w
heapq.heappush(pq, (distances[v], v))
return distances
# 示例使用
if __name__ == "__main__":
# 构建图 (邻接表)
graph = {
'A': [('B', 4), ('C', 2)],
'B': [('C', 3), ('D', 2), ('E', 3)],
'C': [('B', 1), ('D', 4)],
'D': [('E', 5)],
'E': []
}
distances = dijkstra(graph, 'A')
print("Dijkstra 结果:", distances)
# 输出: {'A': 0, 'B': 3, 'C': 2, 'D': 5, 'E': 8}
```
### 2. Bellman-Ford算法
#### 数学公式
对于图 $G=(V,E)$Bellman-Ford算法通过迭代松弛更新每个顶点的最短路径估计
$$d(v) = \min\{d(u) + w(u,v) | (u,v) \in E\}$$
其中:
- $d(v)$ 是从源顶点到顶点 $v$ 的最短路径估计
- $w(u,v)$ 是边 $(u,v)$ 的权重
- 迭代次数最多为 $|V|-1$ 次
#### Python实现
```python
def bellman_ford(graph, source):
"""
Bellman-Ford算法求单源最短路径
参数:
graph: 邻接表表示的图,格式 {u: [(v, w), ...]}
source: 源顶点
返回:
distances: 各顶点到源顶点的最短距离
"""
# 初始化距离
distances = {v: float('inf') for v in graph}
distances[source] = 0
# 获取所有顶点
vertices = list(graph.keys())
# 最多进行 |V|-1 次迭代
for _ in range(len(vertices) - 1):
# 对每条边进行松弛操作
for u in graph:
for v, w in graph[u]:
if distances[u] != float('inf') and distances[u] + w < distances[v]:
distances[v] = distances[u] + w
# 检测负权重环
for u in graph:
for v, w in graph[u]:
if distances[u] != float('inf') and distances[u] + w < distances[v]:
raise ValueError("图中存在负权重环")
return distances
# 示例使用
if __name__ == "__main__":
# 构建图 (邻接表)
graph = {
'A': [('B', 4), ('C', 2)],
'B': [('C', 3), ('D', 2), ('E', 3)],
'C': [('B', 1), ('D', 4)],
'D': [('E', -5)], # 负权重边
'E': []
}
try:
distances = bellman_ford(graph, 'A')
print("Bellman-Ford 结果:", distances)
except ValueError as e:
print(e)
```