Python中使用Kruskal算法求最小生成树

2023-04-11 00:00:00 算法 生成 最小

Kruskal算法是一种求解最小生成树的贪心算法,主要步骤如下:

  1. 将所有边按照权值从小到大排序。
  2. 依次将每条边加入生成树中,如果加入该边后不会形成环,就将该边加入生成树中;否则将该边舍弃。
  3. 重复步骤2,直到生成树中包含了所有顶点。

下面是Python实现Kruskal算法的代码:

# 定义边
class Edge(object):
    def __init__(self, start, end, weight):
        self.start = start
        self.end = end
        self.weight = weight

# 定义图
class Graph(object):
    def __init__(self, vertices):
        self.V = vertices
        self.edges = []

    def add_edge(self, start, end, weight):
        self.edges.append(Edge(start, end, weight))

# 定义并查集
class UnionFind(object):
    def __init__(self, vertices):
        self.parent = {}
        for v in vertices:
            self.parent[v] = v

    def find(self, v):
        if self.parent[v] == v:
            return v
        self.parent[v] = self.find(self.parent[v])
        return self.parent[v]

    def union(self, v1, v2):
        p1 = self.find(v1)
        p2 = self.find(v2)
        self.parent[p1] = p2

# Kruskal算法求最小生成树
def kruskal(g):
    uf = UnionFind(g.V)
    g.edges = sorted(g.edges, key=lambda e: e.weight)
    mst_weight = 0
    mst_edges = []
    for e in g.edges:
        start_root = uf.find(e.start)
        end_root = uf.find(e.end)
        if start_root == end_root:
            continue
        uf.union(e.start, e.end)
        mst_weight += e.weight
        mst_edges.append(e)
    return mst_weight, mst_edges

# 示例
g = Graph(["p", "i", "d", "a", "n", "c", "o", "d", "e", "m"])
g.add_edge("p", "i", 1)
g.add_edge("p", "d", 3)
g.add_edge("i", "d", 2)
g.add_edge("i", "a", 5)
g.add_edge("d", "a", 4)
g.add_edge("a", "n", 8)
g.add_edge("a", "c", 7)
g.add_edge("a", "m", 3)
g.add_edge("n", "c", 6)
g.add_edge("c", "o", 2)
g.add_edge("c", "m", 9)
print(kruskal(g))

上面的代码中,首先定义了边的类Edge和图的类Graph。然后定义了并查集类UnionFind,用于检查加入的边是否会形成环。最后定义了kruskal函数,实现Kruskal算法求解最小生成树。在示例中,我们给出了一个包含10个顶点的图,并求解了其最小生成树。

相关文章