kruskal算法(克鲁斯卡尔算法)python实现
kruskal算法查找最小生成树的方法是:
①首先需要得到整个网络的边集合,并获取每条边权重。
②将连通网中所有的边按照权值大小做升序排序。
③从权值最小的边开始选择,只要此边不和已选择的边一起构成环路,就可以选择它组成最小生成树。
④对于 N 个顶点的连通网,挑选出 N-1 条符合条件的边,这些边组成的生成树就是最小生成树。
其中,在判断是否构成回路时。可以先构建一个存放节点的集合,用来记录已经被选择的节点,当新节点的起点和终点都在此节点集中时,说明构成了回路,则这条边不可用。
from matplotlib import pyplot as plt
# 定义一个表示边的类
class edge:
# 边属性:起点,终点,权重,方向
def __init__(self, start, terminal, weight):
self.start = start
self.terminal = terminal
self.weight = weight
# 边方法:
# 获取边的属性
def getEdge(self):
return [self.start, self.terminal, self.weight]
# 定义一个表示节点的类
class point:
# 节点属性:
def __init__(self):
self.x_coordinate = 0
self.y_coordinate = 0
self.name = None
# 节点方法:
# 设置节点名
def setName(self, name):
self.name = name
# 设置坐标
def setPos(self, pos):
self.x_coordinate = pos[0]
self.y_coordinate = pos[1]
# 邻接矩阵
adjacent_matrix = [[0, 8, 5, 9, 12, 14, 12],
[0, 0, 9, 15, 17, 8, 11],
[0, 0, 0, 7, 9, 11, 7],
[0, 0, 0, 0, 3, 17, 10],
[0, 0, 0, 0, 0, 8, 10],
[0, 0, 0, 0, 0, 0, 9],
[0, 0, 0, 0, 0, 0, 0]]
# 1.根据邻接矩阵获取图的边集和点集
frontier_set = []
nodal_set = []
# 节点数
numbers_of_node = len(adjacent_matrix)
for i in range(numbers_of_node):
node = point() # 创建一个节点
node.setName(chr(i + 65)) # 用ABCD……来命名节点
nodal_set.append(node) # 将新创建的节点加入节点集
# 打印所有节点的名称
for node in nodal_set:
print(node.name, end=" ")
print()
for i in range(numbers_of_node):
for j in range(numbers_of_node):
if adjacent_matrix[i][j]: # 邻接矩阵值不为0表示存在一条边
# 创建一条边,起点为nodal_set[i],终点为nodal_set[j],权重为adjacent_matrix[i][j]
frontier = edge(nodal_set[i], nodal_set[j], adjacent_matrix[i][j])
frontier_set.append(frontier) # 将新创建的边加入边集
# 打印所有的边及其权重
for frontier in frontier_set:
s, t, w = frontier.getEdge()
print([s.name, t.name, w], end=" ")
print()
# 2.按照边的权重大小(从小到大)进行排序
# 冒泡排序
for i in range(len(frontier_set)):
for j in range(len(frontier_set)):
if j > i and frontier_set[i].weight > frontier_set[j].weight:
temp = frontier_set[i]
frontier_set[i] = frontier_set[j]
frontier_set[j] = temp
# 打印结果
for frontier in frontier_set:
s, t, w = frontier.getEdge()
print([s.name, t.name, w], end=" ")
print()
# 3.构造两棵空的(最小)生成树用来放边和点
MST_edge = []
MST_node = []
# 4.往最小生成树中添加节点和边
# num用来记录已经选择的边数量
num = 0
for frontier in frontier_set:
# 如果一条边的起点和终点都在已经生成的树中,则会形成环路,pass
if frontier.start in MST_node and frontier.terminal in MST_node:
pass
else:
MST_edge.append(frontier) # 如果不会形成环路,就把这条边加进去
num += 1 # 已选边的数量+1
if num == numbers_of_node - 1:
break
for frontier in MST_edge:
s, t, w = frontier.getEdge()
print([s.name, t.name, w], end=" ")
print()
# 画图看一下,坐标随便设置,能看清楚就行
nodal_set[0].setPos([1, 2]) # A点坐标(1, 2)
nodal_set[1].setPos([0, 1]) # B点坐标(0, 1)
nodal_set[2].setPos([1, 1]) # C点坐标(1, 1)
nodal_set[3].setPos([2, 1]) # D点坐标(2, 1)
nodal_set[4].setPos([2, 0]) # E点坐标(2, 0)
nodal_set[5].setPos([0, 0]) # F点坐标(0, 0)
nodal_set[6].setPos([1, 0]) # G点坐标(1, 0)
fig = plt.figure()
for node in nodal_set:
plt.plot(node.x_coordinate, node.y_coordinate, "o")
plt.annotate(node.name, xy=(node.x_coordinate, node.y_coordinate))
for frontier in MST_edge:
x1 = frontier.start.x_coordinate
y1 = frontier.start.y_coordinate
x2 = frontier.terminal.x_coordinate
y2 = frontier.terminal.y_coordinate
plt.plot([x1, x2], [y1, y2])
plt.show()
"""
代码输出
A B C D E F G
['A', 'B', 8] ['A', 'C', 5] ['A', 'D', 9] ['A', 'E', 12] ['A', 'F', 14] ['A', 'G', 12] ['B', 'C', 9] ['B', 'D', 15] ['B', 'E', 17] ['B', 'F', 8] ['B', 'G', 11] ['C', 'D', 7] ['C', 'E', 9] ['C', 'F', 11] ['C', 'G', 7] ['D', 'E', 3] ['D', 'F', 17] ['D', 'G', 10] ['E', 'F', 8] ['E', 'G', 10] ['F', 'G', 9]
['D', 'E', 3] ['A', 'C', 5] ['C', 'G', 7] ['C', 'D', 7] ['B', 'F', 8] ['A', 'B', 8] ['E', 'F', 8] ['A', 'D', 9] ['B', 'C', 9] ['C', 'E', 9] ['F', 'G', 9] ['E', 'G', 10] ['D', 'G', 10] ['B', 'G', 11] ['C', 'F', 11] ['A', 'E', 12] ['A', 'G', 12] ['A', 'F', 14] ['B', 'D', 15] ['B', 'E', 17] ['D', 'F', 17]
['D', 'E', 3] ['A', 'C', 5] ['C', 'G', 7] ['C', 'D', 7] ['B', 'F', 8] ['A', 'B', 8]
"""
本文作者:听风者628
本文链接:https://www.cnblogs.com/shuang-fan/p/16180614.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南