📜  Kruskal算法(邻接矩阵的简单实现)(1)

📅  最后修改于: 2023-12-03 15:02:33.428000             🧑  作者: Mango

Kruskal算法(邻接矩阵的简单实现)

Kruskal算法是一种构建最小生成树的贪心算法,是由克鲁斯卡尔(J. Kruskal)在 1956 年发明的。Kruskal算法的主要思想是按照边的权值从小到大选取 n-1 条边,且这 n-1 条边不能形成环,最终构成一个最小生成树。在实际问题中,边的权值有可能重复。

邻接矩阵

邻接矩阵是一种常用的图的表示方法,其基本思想是用一个矩阵来表示一个图。对于 n 个点的图,邻接矩阵是一个 n × n 的矩阵,其元素值表示图中两个结点之间边的信息。当两个结点之间没有边时,对应的元素值为 0,否则为边的权值。

对于无向图(无向边),邻接矩阵是一个对称矩阵;对于有向图(有向边),邻接矩阵是一个非对称矩阵。

Kruskal算法实现步骤
  1. 对于一个大小为 n 的图,初始化 n 个集合,每个集合仅包含一个节点。
  2. 将所有边按照权重从小到大排序。
  3. 依次遍历每一条边,如果两个节点不在同一集合中,将这条边加入到最小生成树中,并将两个节点所在的集合合并为一个集合。
  4. 最终得到的最小生成树为所有已加入边的集合。
Kruskal算法实现

下面是 Kruskal算法在邻接矩阵上的简单实现,代码中使用了 Union-Find 数据结构来实现集合的合并和查找。

from typing import List, Tuple

def find(parent: List[int], i: int) -> int:
    if parent[i] != i:
        parent[i] = find(parent, parent[i])
    return parent[i]

def union(parent: List[int], rank: List[int], x: int, y: int):
    x_root = find(parent, x)
    y_root = find(parent, y)
    if x_root == y_root:
        return
    if rank[x_root] < rank[y_root]:
        parent[x_root] = y_root
    elif rank[x_root] > rank[y_root]:
        parent[y_root] = x_root
    else:
        parent[y_root] = x_root
        rank[x_root] += 1

def kruskal(n: int, edges: List[Tuple[int, int, int]]) -> List[Tuple[int, int, int]]:
    parent = [i for i in range(n)]
    rank = [0 for _ in range(n)]
    result = []
    edges.sort(key=lambda x: x[2]) # 按照边的权值从小到大排序
    for edge in edges:
        u, v, w = edge
        if find(parent, u) != find(parent, v): # 判断是否形成环路
            result.append(edge)
            union(parent, rank, u, v) # 合并集合
    return result
测试

下面是一个测试示例:

n = 5
edges = [(0, 1, 2), (0, 3, 6), (1, 2, 3), (1, 3, 8), (1, 4, 5), (2, 4, 7), (3, 4, 9)]
print(kruskal(n, edges))
# 输出结果:[(0, 1, 2), (1, 2, 3), (1, 4, 5), (0, 3, 6)]

在上面的测试示例中,原始的图如下所示:

   2     3
0-----1-----2
|\   / \   /|
|  5    7  |
|  |     | |
|  8    9  |
|  v     v |
|  4-->3--' |
'--------->'

运行 Kruskal算法后,得到的最小生成树如下所示(边的权值用数字表示):

   2     3
0-----1-----2
   |     |
   |     |
   5     7
         |
         4