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 中国大陆许可协议进行许可。

posted @   听风者628  阅读(447)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
点击右上角即可分享
微信分享提示
💬
评论
📌
收藏
💗
关注
👍
推荐
🚀
回顶
收起
  1. 1 404 not found REOL
404 not found - REOL
00:00 / 00:00
An audio error has occurred.