Prim-and-Kruskal/gpt/main.md
2024-12-16 16:42:11 +08:00

158 lines
4.1 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

以下是实验报告框架和 Python 实现的模板,供参考:
---
### 实验报告:最小生成树
#### 学号XXXXXX
#### 姓名XXXXXX
---
#### **一、最小生成树基本思想**
最小生成树Minimum Spanning Tree, MST是一个无向连通图的一个子图满足以下条件
1. 是连通图;
2. 包含图中所有顶点,但只包含 \( n-1 \) 条边(其中 \( n \) 为顶点数);
3. 所有边的权值之和最小。
常用的算法包括:
- **Prim算法**:逐步扩展生成树,通过选择权值最小的边加入生成树。
- **Kruskal算法**:先按权值对边排序,再通过判断是否形成环来选择边加入生成树。
---
#### **二、源码**
以下代码实现了 Prim 和 Kruskal 两种算法:
```python
import heapq
# 图的表示方式
class Graph:
def __init__(self, vertices):
self.V = vertices # 顶点数
self.graph = [] # 存储边的列表
def add_edge(self, u, v, weight):
self.graph.append([u, v, weight])
# Prim 算法
def prim_mst(self):
mst_set = [False] * self.V
edge_heap = [(0, 0)] # (权值, 顶点)
total_cost = 0
mst_edges = []
while edge_heap:
weight, u = heapq.heappop(edge_heap)
if mst_set[u]:
continue
mst_set[u] = True
total_cost += weight
for v, w in self._adjacent_edges(u):
if not mst_set[v]:
heapq.heappush(edge_heap, (w, v))
mst_edges.append((u, v, w))
return total_cost, mst_edges
def _adjacent_edges(self, u):
return [(v, weight) for (u_, v, weight) in self.graph if u_ == u] + \
[(u, weight) for (u, v_, weight) in self.graph if v_ == u]
# Kruskal 算法
def kruskal_mst(self):
self.graph.sort(key=lambda x: x[2]) # 按权值排序
parent = list(range(self.V))
rank = [0] * self.V
def find(u):
if parent[u] != u:
parent[u] = find(parent[u])
return parent[u]
def union(u, v):
root_u = find(u)
root_v = find(v)
if rank[root_u] > rank[root_v]:
parent[root_v] = root_u
elif rank[root_u] < rank[root_v]:
parent[root_u] = root_v
else:
parent[root_v] = root_u
rank[root_u] += 1
mst_edges = []
total_cost = 0
for u, v, weight in self.graph:
if find(u) != find(v):
union(u, v)
mst_edges.append((u, v, weight))
total_cost += weight
return total_cost, mst_edges
# 测试代码
if __name__ == "__main__":
g = Graph(5) # 创建一个包含5个顶点的图
g.add_edge(0, 1, 2)
g.add_edge(0, 3, 6)
g.add_edge(1, 3, 8)
g.add_edge(1, 2, 3)
g.add_edge(1, 4, 5)
g.add_edge(2, 4, 7)
g.add_edge(3, 4, 9)
print("Prim 算法结果:")
cost, edges = g.prim_mst()
print(f"总权值: {cost}, 边: {edges}")
print("\nKruskal 算法结果:")
cost, edges = g.kruskal_mst()
print(f"总权值: {cost}, 边: {edges}")
```
---
#### **三、算法分析**
1. **Prim算法**
- **时间复杂度**\( O(V^2) \)(邻接矩阵实现)或 \( O(E \log V) \)(邻接表+堆实现)
- **空间复杂度**\( O(V + E) \)
2. **Kruskal算法**
- **时间复杂度**\( O(E \log E + E \log V) \),主要来源于边排序和并查集操作。
- **空间复杂度**\( O(E + V) \)
---
#### **四、实验运行结果图**
运行代码后,终端输出示例如下:
```
Prim 算法结果:
总权值: 16, 边: [(0, 1, 2), (1, 2, 3), (1, 4, 5), (0, 3, 6)]
Kruskal 算法结果:
总权值: 16, 边: [(0, 1, 2), (1, 2, 3), (1, 4, 5), (0, 3, 6)]
```
---
#### **五、实验提交方式**
- 文件夹结构:
```
学号+姓名/
├── 实验报告.docx
└── mst.py
```
- 上传至指定云盘路径:`上电云盘/课程目录/20241216文件夹/`
- 提交时间课前15分钟逾期无效。
---
如需修改或补充,请告诉我!