相关概念
连通图:在无向图中,若任意两个顶点vi和vj都有路径相通,则称该无向图为连通图。连通网:在连通图的基础上,每条边赋予了一定的权值(代价)就构成了连通网。
生成树:一个连通图的生成树是一个连通子图;它含有图中全部n个顶点,但只有n-1条边。
最小生成树:在连通网的所有生成树中,所有边的代价和最小的生成树。
图例
Prim算法
1.算法思想
- 图的所有顶点集合为V,操作集合X初始化为{“A”},操作集合Y=V-X;(X表示加入生成树顶点集,Y表示未加入生成树的顶点集)
- 在顶点集合X和Y之间组成的所有边中,选择一个代价最小的边(Xi,Yj), 加入到最小生成树中,并把顶点Yj加入到顶点集合X中。
- 重复之上的步骤,直到产生n-1条边或者X的顶点集合元素个数为n
2.图例
3.python编码实现
# 定义生成Y集合的方法
def create_Y(X):
Y = []
for point in V:
if point not in X:
Y.append(point)
return Y
"""###################################
#编写Prim算法
# 1.变量定义
# weight:存放最小边权值
# point1:存放Prim算法后找到的边的起点
# point2:存放Prim算法后找到的边的终点
# 2.Prim算法
###################################"""
#编写Prim算法
def Prim(V, E):
# 1.定义变量
weight = 1000
point1 = ""
point2 = ""
# 2.编写Prim算法
for i in range(len(V)):
if V[i] in X: # 确定了顶点集合X中元素在顶点集合V中的下标,间接的确定了在边集合中的一个下标
for j in range(len(V)):
if V[j] in create_Y(X): # 确定了顶点集合Y中元素在集合V中的下标,间接确定了在边集合中的另一个下标
if (E[i][j] != -1) and (E[i][j] < weight): # 循环判断,找到顶点集合X到Y之间最小权值的边
weight = E[i][j]
point1 = V[i]
point2 = V[j]
print(weight, point1 + "---" + point2) # 将生成树的这条边进行显示
X.append(point2) #将该点加入到操作集合X中
if __name__ == "__main__":
"""###################################
#构造带权的连通图
# 1.构造顶点集合V
# 2.构造边集合E
# 3.创建操作集合X和Y(X表示加入生成树点的集合,Y表示未加入生成树点的集合)
###################################"""
# 1.构造顶点集合V
V = ["A", "B", "C", "D", "E", "F"]
# 2.构造边集合E
E = [[0, 6, 1, 5, -1, -1],
[6, 0, 5, -1, 3, -1],
[1, 5, 0, 5, 6, 4],
[5, -1, 5, 0, -1, 2],
[-1, 3, 6, -1, 0, 6],
[-1, -1, 4, 2, 6, 0]]
# 3.创建操作集合X和Y
X = ["A"]
#4. 定义一个循环变量count(统计生成树中边的个数)
count = 0
while True:
if count < len(V)-1:
Prim(V, E)
count = count + 1
else:
break