Kruskal算法(Python实现)

Kruskal算法是一种用来查找最小生成树的算法,由Joseph Kruskal在1956年发表。用来解决同样问题的还有Prim算法和Boruvka算法等。三种算法都是贪心算法的应用。和Boruvka算法不同的地方是,Kruskal算法在图中存在相同权值的边时也有效。

算法描述

  1. 新建图G,G中拥有原图中相同的节点,但没有边
  2. 将原图中所有的边按权值从小到大排序
  3. 从权值最小的边开始,如果这条边连接的两个节点于图G中不在同一个连通分量中,则添加这条边到图G中
  4. 重复3,直至图G中所有的节点都在同一个连通分量中

算法示例

在这里插入图片描述
在这里插入图片描述

代码实现:

对于图:
在这里插入图片描述

# 以全局变量X定义节点集合,即类似{'A':'A','B':'B','C':'C','D':'D'},如果A、B两点连通,则会更改为{'A':'B','B':'B",...},即任何两点连通之后,两点的值value将相同。
X = dict()
R = dict() # 各点的初始等级均为0,如果被做为连接的的末端,则增加1

def make_set(point):
    X[point] = point
    R[point] = 0
def find(point):
    if X[point] != point:
        X[point] = find(X[point])
    return X[point]
def merge(point1, point2):
    '''连接两个分量(节点)
    '''
    r1 = find(point1)
    r2 = find(point2)
    if r1 != r2:
        if R[r1] > R[r2]:
            X[r2] = r1
        else:
            X[r1] = r2
            if R[r1] == R[r2]:
                R[r2] += 1
def kruskal(vertices,edges):
    '''KRUSKAL算法实现
    '''
    for vertice in vertices:
        make_set(vertice)
    minu_tree = []
    edges.sort()  # 按照权重从小到大排序
    for edge in edges:
        weight, vertice1, vertice2 = edge
        if find(vertice1) != find(vertice2):
            merge(vertice1, vertice2)
            minu_tree.append(edge)
    return minu_tree


vertices = ['A', 'B', 'C', 'D', 'E', 'F', 'G']
edges = [(7, 'A', 'B'),
            (5, 'A', 'D'),
            (8, 'B', 'C'),
            (9, 'B', 'D'),
            (7, 'B', 'E'),
            (5, 'C', 'E'),
            (15, 'D', 'E'),
            (6, 'D', 'F'),
            (8, 'E', 'F'),
            (9, 'E', 'G'),
            (11, 'F', 'G'),
            ]
print(kruskal(vertices,edges))

输出为:

[(5, 'A', 'D'), (5, 'C', 'E'), (6, 'D', 'F'), (7, 'A', 'B'), (7, 'B', 'E'), (9, 'E', 'G')]
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值