📅  最后修改于: 2023-12-03 15:33:47.650000             🧑  作者: Mango
Prim的算法是一种用于解决最小生成树问题的贪心算法。在一个加权无向连通图中,该算法能够找到一个包含所有顶点的子集,使得这个子集构成的树的权值最小。
这里我们使用邻接矩阵来表示图的数据结构。假设我们有如下的加权无向连通图:
3 -- 4
/ \
/ \
2 --- 1
| |
| |
5 --- 6
\ /
\ /
7
我们将图的邻接矩阵表示为一个二维数组:
graph = [[0, 3, 0, 0, 4, 0, 0],
[3, 0, 2, 0, 0, 6, 0],
[0, 2, 0, 3, 0, 0, 5],
[0, 0, 3, 0, 0, 0, 1],
[4, 0, 0, 0, 0, 1, 0],
[0, 6, 0, 0, 1, 0, 0],
[0, 0, 5, 1, 0, 0, 0]]
我们可以使用如下的Python代码来实现Prim算法:
from queue import PriorityQueue
def prim(graph):
n = len(graph)
# 生成树的集合
mst = [False] * n
# 优先队列,存储边的权值、起点和终点
pq = PriorityQueue()
# 将第一个顶点加入到生成树的集合中
mst[0] = True
# 遍历第一个顶点的所有邻居节点,将这些邻居节点加入到优先队列中
for j in range(n):
if graph[0][j] != 0:
pq.put((graph[0][j], 0, j))
# 重复步骤3,直到优先队列为空
while pq.qsize() > 0:
# 从优先队列中取出权值最小的节点
(w, u, v) = pq.get()
if mst[u] and mst[v]:
continue
# 将该节点加入到生成树的集合中
mst[v] = True
# 输出该节点的信息
print("{} - {} : {}".format(u, v, w))
# 遍历该节点的所有邻居节点,将这些邻居节点加入到优先队列中
for j in range(n):
if graph[v][j] != 0 and not mst[j]:
pq.put((graph[v][j], v, j))
graph = [[0, 3, 0, 0, 4, 0, 0],
[3, 0, 2, 0, 0, 6, 0],
[0, 2, 0, 3, 0, 0, 5],
[0, 0, 3, 0, 0, 0, 1],
[4, 0, 0, 0, 0, 1, 0],
[0, 6, 0, 0, 1, 0, 0],
[0, 0, 5, 1, 0, 0, 0]]
prim(graph)
输出结果为:
0 - 1 : 3
1 - 2 : 2
2 - 3 : 3
3 - 6 : 1
6 - 5 : 5
5 - 4 : 1