最小生成树Kruskal算法—python实现

本文介绍了一种使用Kruskal算法生成无向图最小生成树的方法,并提供了两种不同的实现方式:一种是基于不相交集的数据结构来避免环路;另一种则通过检查每条边的两个节点是否已连接。

两种实现方法

class DisjointSet(dict):
    '''不相交集'''

    def __init__(self, dict):
        pass

    def add(self, item):
        self[item] = item

    def find(self, item):
        if self[item] != item:
            self[item] = self.find(self[item])
        return self[item]

    def unionset(self, item1, item2):
        self[item2] = self[item1]


def Kruskal_1(nodes, edges):
    '''基于不相交集实现Kruskal算法'''
    forest = DisjointSet(nodes)
    MST = []
    for item in nodes:
        print(item)
        forest.add(item)
    edges = sorted(edges, key=lambda element: element[2])
    num_sides = len(nodes)-1  # 最小生成树的边数等于顶点数减一
    for e in edges:
        node1, node2, _ = e
        parent1 = forest.find(node1)
        parent2 = forest.find(node2)
        if parent1 != parent2:
            MST.append(e)
            num_sides -= 1
            if num_sides == 0:
                return MST
            else:
                forest.unionset(parent1, parent2)
    pass


def Kruskal(nodes, edges):
    ''' Kruskal 无向图生成最小生成树 '''
    all_nodes = nodes  # set(nodes)
    used_nodes = set()
    MST = []
    edges = sorted(edges, key=lambda element: element[2], reverse=True)
    # 对所有的边按权重升序排列
    while used_nodes != all_nodes and edges:
        element = edges.pop(-1)
        if element[0] in used_nodes and element[1] in used_nodes:
            continue
        MST.append(element)
        used_nodes.update(element[:2])
        # print(used_nodes)
    return MST


def main():
    nodes = set(list('ABCDEFGHI'))
    edges = [("A", "B", 4), ("A", "H", 8),
             ("B", "C", 8), ("B", "H", 11),
             ("C", "D", 7), ("C", "F", 4),
             ("C", "I", 2), ("D", "E", 9),
             ("D", "F", 14), ("E", "F", 10),
             ("F", "G", 2), ("G", "H", 1),
             ("G", "I", 6), ("H", "I", 7)]
    print("\n\nThe undirected graph is :", edges)
    print("\n\nThe minimum spanning tree by Kruskal is : ")
    print(Kruskal_1(nodes, edges))


if __name__ == '__main__':
    main()

Kruskal算法是一种用于求解最小生成树的贪心算法。下面是Kruskal算法Python代码实现: ```python # 定义边的类 class Edge: def __init__(self, src, dest, weight): self.src = src self.dest = dest self.weight = weight # 定义并查集类 class UnionFind: def __init__(self, vertices): self.parent = {} self.rank = {} for v in vertices: self.parent[v] = v self.rank[v] = 0 def find(self, v): if self.parent[v] != v: self.parent[v] = self.find(self.parent[v]) return self.parent[v] def union(self, v1, v2): root1 = self.find(v1) root2 = self.find(v2) if root1 != root2: if self.rank[root1] < self.rank[root2]: self.parent[root1] = root2 elif self.rank[root1] > self.rank[root2]: self.parent[root2] = root1 else: self.parent[root2] = root1 self.rank[root1] += 1 # Kruskal算法实现 def kruskal(vertices, edges): # 根据边的权重对边进行排序 edges.sort(key=lambda x: x.weight) # 创建并查集对象 uf = UnionFind(vertices) # 存储最小生成树的边 mst = [] for edge in edges: src_root = uf.find(edge.src) dest_root = uf.find(edge.dest) # 如果边的两个顶点不在同一个连通分量中,则将边加入最小生成树 if src_root != dest_root: mst.append(edge) uf.union(src_root, dest_root) return mst # 测试代码 vertices = ['A', 'B', 'C', 'D', 'E'] edges = [ Edge('A', 'B', 4), Edge('A', 'C', 1), Edge('B', 'C', 3), Edge('B', 'D', 2), Edge('C', 'D', 4), Edge('C', 'E', 5), Edge('D', 'E', 1) ] mst = kruskal(vertices, edges) for edge in mst: print(f"{edge.src} - {edge.dest}: {edge.weight}") ```
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值