Kruskalアルゴリズムは、グラフの最小全域木(MST)を見つけるための効率的な手法です。このアルゴリズムは、辺を重みの昇順にソートし、最小の重みを持つ辺から順に選択していき、サイクルを形成しないように注意しながら進めます。Union-Find(またはディスジョイントセット)は、サイクルを検出し、異なる集合を効率的に管理するために使用されます。
Union-Findは、集合の管理を効率的に行うためのデータ構造です。以下の二つの主要な操作を提供します。
Union-Findは、パス圧縮とランク(サイズ)による統合を行うことで、これらの操作を非常に効率的に実行します。
以下に、Kruskalアルゴリズムの実装を示します。この実装にはUnion-Findも含まれています。
class UnionFind:
def __init__(self, size):
self.parent = [i for i in range(size)]
self.rank = [1] * size
def find(self, p):
if self.parent[p] != p:
self.parent[p] = self.find(self.parent[p]) # Path compression
return self.parent[p]
def union(self, p, q):
rootP = self.find(p)
rootQ = self.find(q)
if rootP != rootQ:
# Union by rank
if self.rank[rootP] > self.rank[rootQ]:
self.parent[rootQ] = rootP
elif self.rank[rootP] < self.rank[rootQ]:
self.parent[rootP] = rootQ
else:
self.parent[rootQ] = rootP
self.rank[rootP] += 1
class Edge:
def __init__(self, u, v, weight):
self.u = u
self.v = v
self.weight = weight
def kruskal(vertices, edges):
edges.sort(key=lambda edge: edge.weight) # Sort edges by weight
uf = UnionFind(vertices)
mst = []
for edge in edges:
if uf.find(edge.u) != uf.find(edge.v):
uf.union(edge.u, edge.v)
mst.append(edge)
return mst
# Example usage
vertices = 4
edges = [
Edge(0, 1, 10),
Edge(0, 2, 6),
Edge(0, 3, 5),
Edge(1, 3, 15),
Edge(2, 3, 4)
]
mst = kruskal(vertices, edges)
for edge in mst:
print(f"Edge: {edge.u} - {edge.v} with weight: {edge.weight}")
__init__
: 親ノードとランクを初期化します。find
: 指定した要素の親を再帰的に見つけ、パス圧縮を行います。union
: 二つの要素を結合し、ランクに基づいて木の高さを最小限に保ちます。
Edgeクラス:
辺の情報(端点と重み)を持っています。
kruskal関数:
辺を重みでソートし、Union-Findを使用して最小全域木を構成します。
例の使用法:
このコードを実行すると、最小全域木に含まれる辺が表示されます。これにより、KruskalアルゴリズムとUnion-Findの基本的な理解が深まるでしょう。