Python
Python

 

 

The Minimum Spanning Tree (MST) problem is a cornerstone in the field of graph theory and has numerous applications in network design, clustering, and more. Kruskal’s algorithm is one of the most efficient and widely used algorithms to find the MST of a connected, undirected graph. This article provides a comprehensive guide to implementing Kruskal’s algorithm in Python, complete with detailed explanations, program structure, and documentation.

Understanding the Minimum Spanning Tree (MST)

A Minimum Spanning Tree of a graph is a subset of its edges that connects all the vertices together, without any cycles, and with the minimum possible total edge weight. In other words, it is a tree that spans all the vertices with the least total edge cost.

Applications of MST

  • Network Design: Designing efficient networks such as computer networks, telecommunications, and transportation systems.
  • Clustering: Grouping data points in machine learning and data analysis.
  • Approximation Algorithms: Solving problems like the Traveling Salesman Problem (TSP) through MST-based heuristics.

Kruskal’s Algorithm Overview

Kruskal’s algorithm is a greedy algorithm that finds an MST by selecting the smallest available edge that doesn’t form a cycle with the already included edges. The algorithm continues this process until all vertices are connected.

Steps of Kruskal’s Algorithm

  1. Sort all edges: Sort the edges of the graph in non-decreasing order of their weights.
  2. Initialize MST: Start with an empty MST.
  3. Iterate through sorted edges:
    • Select the smallest edge.
    • Check if adding this edge creates a cycle using the Union-Find data structure.
    • If it doesn’t create a cycle, include it in the MST.
    • Repeat until the MST contains (V-1) edges, where V is the number of vertices.

Program Structure and Explanation

The Python program to implement Kruskal’s algorithm is structured into several key components:

  • Graph Representation: The graph is represented using an edge list, where each edge is a tuple containing two vertices and the weight of the edge.
  • Union-Find Data Structure: This structure helps in efficiently managing and merging disjoint sets to detect cycles.
  • Kruskal’s Algorithm Implementation: The main function that sorts the edges and constructs the MST by selecting edges that do not form a cycle.
  • Main Function: To execute the program with example graphs and display the results.

Python Program: Kruskal’s Algorithm


# Kruskal's Algorithm to find the Minimum Spanning Tree (MST) of a graph

class UnionFind:
    """
    Union-Find (Disjoint Set) data structure implementation with path compression and union by rank.
    """

    def __init__(self, vertices):
        """
        Initialize the Union-Find structure.

        Parameters:
        vertices (list): A list of vertices in the graph.
        """
        self.parent = {vertex: vertex for vertex in vertices}
        self.rank = {vertex: 0 for vertex in vertices}

    def find(self, vertex):
        """
        Find the root parent of the vertex with path compression.

        Parameters:
        vertex (any): The vertex to find.

        Returns:
        any: The root parent of the vertex.
        """
        if self.parent[vertex] != vertex:
            self.parent[vertex] = self.find(self.parent[vertex])  # Path compression
        return self.parent[vertex]

    def union(self, vertex1, vertex2):
        """
        Union the sets containing vertex1 and vertex2 using union by rank.

        Parameters:
        vertex1 (any): The first vertex.
        vertex2 (any): The second vertex.

        Returns:
        bool: True if union was successful (no cycle), False otherwise.
        """
        root1 = self.find(vertex1)
        root2 = self.find(vertex2)

        if root1 == root2:
            return False  # Cycle detected

        # Union by rank
        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

        return True

def kruskal_mst(vertices, edges):
    """
    Kruskal's algorithm to find the Minimum Spanning Tree (MST) of a graph.

    Parameters:
    vertices (list): A list of vertices in the graph.
    edges (list of tuples): A list of edges represented as (weight, vertex1, vertex2).

    Returns:
    list: A list of edges that form the MST.
    """
    # Sort edges based on ascending weight
    sorted_edges = sorted(edges, key=lambda edge: edge[0])
    
    uf = UnionFind(vertices)
    mst = []

    for edge in sorted_edges:
        weight, vertex1, vertex2 = edge
        if uf.union(vertex1, vertex2):
            mst.append(edge)
            if len(mst) == len(vertices) - 1:
                break

    return mst

def main():
    """
    Main function to execute Kruskal's algorithm on example graphs.
    """
    # Example 1
    print("Example 1:")
    vertices1 = ['A', 'B', 'C', 'D', 'E', 'F']
    edges1 = [
        (1, 'A', 'B'),
        (3, 'A', 'C'),
        (3, 'B', 'C'),
        (6, 'B', 'D'),
        (4, 'C', 'D'),
        (2, 'C', 'E'),
        (5, 'D', 'E'),
        (4, 'D', 'F'),
        (5, 'E', 'F')
    ]

    mst1 = kruskal_mst(vertices1, edges1)
    print("Minimum Spanning Tree edges:")
    for edge in mst1:
        print(f"{edge[1]} - {edge[2]} (Weight: {edge[0]})")
    total_weight1 = sum([edge[0] for edge in mst1])
    print(f"Total Weight of MST: {total_weight1}\n")

    # Example 2
    print("Example 2:")
    vertices2 = ['S', 'T', 'X', 'Y', 'Z']
    edges2 = [
        (10, 'S', 'T'),
        (1, 'S', 'X'),
        (3, 'T', 'X'),
        (1, 'T', 'Y'),
        (4, 'X', 'Y'),
        (2, 'Y', 'Z'),
        (8, 'X', 'Z')
    ]

    mst2 = kruskal_mst(vertices2, edges2)
    print("Minimum Spanning Tree edges:")
    for edge in mst2:
        print(f"{edge[1]} - {edge[2]} (Weight: {edge[0]})")
    total_weight2 = sum([edge[0] for edge in mst2])
    print(f"Total Weight of MST: {total_weight2}")

if __name__ == "__main__":
    main()
    

Program Documentation

Class: UnionFind

Implements the Union-Find (Disjoint Set) data structure with path compression and union by rank optimizations. This structure is essential for efficiently detecting cycles during the execution of Kruskal’s algorithm.

  • Method: __init__(self, vertices)
    • Initializes the parent and rank dictionaries for each vertex.
  • Method: find(self, vertex)
    • Finds the root parent of the given vertex with path compression.
  • Method: union(self, vertex1, vertex2)
    • Unites the sets containing vertex1 and vertex2 using union by rank. Returns False if a cycle is detected, True otherwise.

Function: kruskal_mst(vertices, edges)

Implements Kruskal’s algorithm to find the Minimum Spanning Tree (MST) of a given graph.

  • Parameters:
    • vertices (list): A list of all vertices in the graph.
    • edges (list of tuples): A list of edges where each edge is represented as (weight, vertex1, vertex2).
  • Returns:
    • list: A list of edges that constitute the MST.

Function: main()

Serves as the entry point of the program. It defines example graphs, executes Kruskal’s algorithm, and displays the resulting MST and its total weight.

How to Run the Program

    1. Ensure you have Python installed on your system (Python 3.x recommended).
    2. Copy the provided Python code into a file named kruskal_mst.py.
    3. Open a terminal or command prompt and navigate to the directory containing the kruskal_mst.py file.
    4. Run the program using the command:
python kruskal_mst.py
  1. The program will execute the defined examples and output the edges in the MST along with the total weight.

Example Output


Example 1:
Minimum Spanning Tree edges:
A - B (Weight: 1)
C - E (Weight: 2)
B - D (Weight: 6)
A - C (Weight: 3)
D - F (Weight: 4)
Total Weight of MST: 16

Example 2:
Minimum Spanning Tree edges:
S - X (Weight: 1)
T - Y (Weight: 1)
Y - Z (Weight: 2)
T - X (Weight: 3)
Total Weight of MST: 7
    

Customization

To use the program with different graphs, modify the vertices and edges lists within the main function. Ensure that:

  • All vertices are listed in the vertices list.
  • Each edge is represented as a tuple with the format (weight, vertex1, vertex2).

For example, to represent a graph with vertices [‘P’, ‘Q’, ‘R’, ‘S’] and edges with corresponding weights:


# New Example
vertices = ['P', 'Q', 'R', 'S']
edges = [
    (2, 'P', 'Q'),
    (3, 'P', 'R'),
    (1, 'Q', 'R'),
    (4, 'Q', 'S'),
    (5, 'R', 'S')
]
    

Adding this new example to the main function will allow you to compute the MST for the specified graph.

Conclusion

Kruskal’s algorithm is a powerful and efficient method for finding the Minimum Spanning Tree of a graph. By leveraging the Union-Find data structure, the algorithm ensures optimal performance even for larger graphs. This Python implementation provides a clear and concise way to understand and apply Kruskal’s algorithm to various graph-related problems. Whether you’re working on network design, clustering, or other applications, mastering Kruskal’s algorithm is an invaluable asset in your algorithmic toolkit.


Learn how to find the Minimum Spanning Tree using Kruskal’s Algorithm in Python. This guide includes detailed program structure, documentation, and example usage.

 

By Aditya Bhuyan

I work as a cloud specialist. In addition to being an architect and SRE specialist, I work as a cloud engineer and developer. I have assisted my clients in converting their antiquated programmes into contemporary microservices that operate on various cloud computing platforms such as AWS, GCP, Azure, or VMware Tanzu, as well as orchestration systems such as Docker Swarm or Kubernetes. For over twenty years, I have been employed in the IT sector as a Java developer, J2EE architect, scrum master, and instructor. I write about Cloud Native and Cloud often. Bangalore, India is where my family and I call home. I maintain my physical and mental fitness by doing a lot of yoga and meditation.

Leave a Reply

Your email address will not be published. Required fields are marked *

error

Enjoy this blog? Please spread the word :)