Kruskal's Algorithm is a well-known algorithm used to find the Minimum Spanning Tree (MST) of a connected, undirected graph. An MST is a subset of the edges that connects all vertices together, without any cycles and with the minimum possible total edge weight. This algorithm is particularly useful in network design, such as designing efficient road networks or electrical grids.
Before diving into Kruskal's Algorithm, it's essential to understand the following concepts:
Kruskal's Algorithm works by iteratively adding the next lightest edge that does not form a cycle with the spanning tree formed so far. The algorithm can be broken down into the following steps:
Below is a Python implementation of Kruskal's Algorithm using an adjacency list representation for the graph and a disjoint set data structure:
class Graph:
def __init__(self, vertices):
self.V = vertices
self.graph = []
# Function to add an edge to the graph
def add_edge(self, u, v, w):
self.graph.append([u, v, w])
# A utility function to find set of an element i (uses path compression)
def find(self, parent, i):
if parent[i] == i:
return i
return self.find(parent, parent[i])
# A function that does union of two sets of x and y (uses union by rank)
def union(self, parent, rank, x, y):
xroot = self.find(parent, x)
yroot = self.find(parent, y)
# Attach smaller rank tree under root of high rank tree
if rank[xroot] < rank[yroot]:
parent[xroot] = yroot
elif rank[xroot] > rank[yroot]:
parent[yroot] = xroot
# If ranks are same, then make one as root and increment its rank by one
else:
parent[yroot] = xroot
rank[xroot] += 1
# The main function to construct MST using Kruskal's algorithm
def kruskal_mst(self):
result = [] # This will store the resultant MST
i = 0 # An index variable, used for sorted edges
e = 0 # An index variable, used for result[]
# Step 1: Sort all the edges in non-decreasing order of their weight
self.graph = sorted(self.graph, key=lambda item: item[2])
parent = []
rank = []
# Create V subsets with single elements
for node in range(self.V):
parent.append(node)
rank.append(0)
# Number of edges to be taken is equal to V-1
while e < self.V - 1:
# Step 2: Pick the smallest edge and increment the index for next iteration
u, v, w = self.graph[i]
i += 1
x = self.find(parent, u)
y = self.find(parent, v)
# If including this edge does't cause cycle, include it in result
if x != y:
e = e + 1
result.append([u, v, w])
self.union(parent, rank, x, y)
# Print the contents of result[] to display the built MST
print("Following are the edges in the constructed MST")
for u, v, weight in result:
print(f"{u} -- {v} == {weight}")
# Driver code
if __name__ == "__main__":
g = Graph(4)
g.add_edge(0, 1, 10)
g.add_edge(0, 2, 6)
g.add_edge(0, 3, 5)
g.add_edge(1, 3, 15)
g.add_edge(2, 3, 4)
g.kruskal_mst()
Kruskal's Algorithm is a powerful tool for finding the MST of a graph. Its simplicity and efficiency make it suitable for a wide range of applications. By understanding its implementation and best practices, you can effectively use Kruskal's Algorithm in your projects involving network design and optimization problems.