📅  最后修改于: 2023-12-03 14:56:16.882000             🧑  作者: Mango
生成树是指在一个连通图中,选取一些边和顶点,形成一个不包含回路的子图,即生成树。生成树包含原图所有顶点,但只包含足以支撑这个图的边。
生成树有很多实际的应用。其中一些:
网络设计:用生成树来连通网络,保证每个节点都可以被访问到。
最优化问题:在一些最优化问题中,我们需要分别找到最大和最小的生成树,来寻找最优的方案。
与生成树相似,最小生成树也是一个连通图的子图。最小生成树是指其边的总权值最小的生成树。
最小生成树也有很多实际的应用。其中一些:
网络设计:用最小生成树来连接所有的节点,保证网络的总成本最小。
群体聚类:将数据集聚类成若干子集时,使用最小生成树提取共性。
Kruskal算法是解决最小生成树问题的一个经典算法。它的思路是先将所有边按权值从小到大排序,对于每个边,若该边所连接的两个节点不在同一个集合中,就将这两个节点所在的集合合并,并将该边加入最小生成树中。重复此过程,直到所有的边都被加入最小生成树为止。
def find(parent, i):
if parent[i] == i:
return i
return find(parent, parent[i])
def union(parent, rank, x, y):
xroot = find(parent, x)
yroot = find(parent, y)
if rank[xroot] < rank[yroot]:
parent[xroot] = yroot
elif rank[xroot] > rank[yroot]:
parent[yroot] = xroot
else :
parent[yroot] = xroot
rank[xroot] += 1
def kruskalMST(graph, V):
result =[] # 存储最小生成树的边
i = 0 # 排序后的边下标
e = 0 # 已经添加到最小生成树中的边的数量
graph = sorted(graph,key=lambda item: item[2]) # 根据权值排序的边列表
parent = [] ; rank = []
for node in range(V):
parent.append(node)
rank.append(0)
while e < V -1 :
u,v,w = graph[i]
i = i + 1
x = find(parent, u)
y = find(parent ,v)
if x != y:
e = e + 1
result.append([u,v,w])
union(parent, rank, x, y)
return result
Prim算法也是解决最小生成树问题的一个经典算法。它的思路是从一个节点开始,每次选择与当前生成树相邻的最小边加入最小生成树,直到所有节点都在最小生成树中为止。
import sys
class Graph():
def __init__(self, vertices):
self.V = vertices
self.graph = [[0 for column in range(vertices)]
for row in range(vertices)]
def printMST(self, parent):
print("Edge \tWeight")
for i in range(1, self.V):
print(parent[i], "-", i, "\t", self.graph[i][ parent[i] ])
def minKey(self, key, mstSet):
min = sys.maxsize # 初始化最小值
for v in range(self.V):
if key[v] < min and mstSet[v] == False:
min = key[v]
min_index = v
return min_index
def primMST(self):
key = [sys.maxsize] * self.V # 最小边的权值列表
parent = [None] * self.V # 存储最小生成树中节点的父节点
key[0] = 0 # 0号节点是根节点
mstSet = [False] * self.V
parent[0] = -1 # 初始化根节点为-1
for cout in range(self.V):
u = self.minKey(key, mstSet) # 从未处理的节点中选取一个最小的节点
mstSet[u] = True # 标记该节点已经处理过了
for v in range(self.V):
if self.graph[u][v] > 0 and mstSet[v] == False and key[v] > self.graph[u][v]:
key[v] = self.graph[u][v]
parent[v] = u
self.printMST(parent)
g = Graph(5)
g.graph = [[0, 2, 0, 6, 0],
[2, 0, 3, 8, 5],
[0, 3, 0, 0, 7],
[6, 8, 0, 0, 9],
[0, 5, 7, 9, 0]]
g.primMST();