| 
 | 1 | +# Author: OMKAR PATHAK  | 
 | 2 | + | 
 | 3 | +# A greedy algorithm example  | 
 | 4 | + | 
 | 5 | +# Algorithm:  | 
 | 6 | +# 1. T (the final spanning tree) is defined to be the empty set;  | 
 | 7 | +# 2. For each vertex v of G, make the empty set out of v;  | 
 | 8 | +# 3. Sort the edges of G in ascending (non-decreasing) order;  | 
 | 9 | +# 4. For each edge (u, v) from the sored list of step 3.  | 
 | 10 | +#       If u and v belong to different sets  | 
 | 11 | +#          Add (u,v) to T;  | 
 | 12 | +#          Get together u and v in one single set;  | 
 | 13 | +# 5. Return T  | 
 | 14 | + | 
 | 15 | +# from collections import defaultdict  | 
 | 16 | + | 
 | 17 | +class Graph:  | 
 | 18 | + | 
 | 19 | +    def __init__(self, vertices):  | 
 | 20 | +        self.vertices = vertices  | 
 | 21 | +        self.graph = []  | 
 | 22 | + | 
 | 23 | +    # function to add an edge to graph  | 
 | 24 | +    def addEdge(self, fromEdge, toEdge, weight):  | 
 | 25 | +        self.graph.append([fromEdge, toEdge, weight])  | 
 | 26 | + | 
 | 27 | +    # function to find the index of element i  | 
 | 28 | +    def find(self, parent, i):  | 
 | 29 | +        if parent[i] == i:  | 
 | 30 | +            return i  | 
 | 31 | +        return self.find(parent, parent[i])  | 
 | 32 | + | 
 | 33 | +    # function that finds the union of two sets first and second  | 
 | 34 | +    def union(self, parent, rank, first, second):  | 
 | 35 | +        root_x = self.find(parent, first)  | 
 | 36 | +        root_y = self.find(parent, second)  | 
 | 37 | + | 
 | 38 | +        if rank[root_x] < rank[root_y]:  | 
 | 39 | +            parent[root_x] = root_y  | 
 | 40 | +        elif rank[root_x] > rank[root_y]:  | 
 | 41 | +            parent[root_y] = root_x  | 
 | 42 | +        # if ranks are same then increment its rank  | 
 | 43 | +        elif rank[root_x] == rank[root_y]:  | 
 | 44 | +            parent[root_y] = root_x  | 
 | 45 | +            rank[root_x] += 1  | 
 | 46 | + | 
 | 47 | +    def kruskals(self):  | 
 | 48 | +        result = []  | 
 | 49 | + | 
 | 50 | +        sortedIndex = 0  | 
 | 51 | +        resultIndex = 0  | 
 | 52 | + | 
 | 53 | +        # sort all the edges according to their weights inn ascending order  | 
 | 54 | +        self.graph =  sorted(self.graph,key=lambda item: item[2])  | 
 | 55 | + | 
 | 56 | +        parent = []  | 
 | 57 | +        rank = []  | 
 | 58 | + | 
 | 59 | +        for node in range(self.vertices):  | 
 | 60 | +            parent.append(node)  | 
 | 61 | +            rank.append(0)  | 
 | 62 | + | 
 | 63 | +        while resultIndex < self.vertices - 1:  | 
 | 64 | +            fromEdge, toEdge, weight = self.graph[sortedIndex]  | 
 | 65 | + | 
 | 66 | +            sortedIndex += 1  | 
 | 67 | +            root_x = self.find(parent, fromEdge)  | 
 | 68 | +            root_y = self.find(parent, toEdge)  | 
 | 69 | + | 
 | 70 | +            if root_x != root_y:  | 
 | 71 | +                resultIndex += 1  | 
 | 72 | +                result.append([fromEdge, toEdge, weight])  | 
 | 73 | +                self.union(parent, rank, root_x, root_y)  | 
 | 74 | + | 
 | 75 | +        # print the contents of result[] to display the built MST  | 
 | 76 | +        print ('Constructed Kruskal\'s Minimum Spanning Tree: ')  | 
 | 77 | +        for u,v,weight  in result:  | 
 | 78 | +            print('{} -> {} = {}'.format(u, v, weight))  | 
 | 79 | + | 
 | 80 | +if __name__ == '__main__':  | 
 | 81 | +    g = Graph(4)  | 
 | 82 | +    g.addEdge(0, 1, 10)  | 
 | 83 | +    g.addEdge(0, 2, 6)  | 
 | 84 | +    g.addEdge(0, 3, 5)  | 
 | 85 | +    g.addEdge(1, 3, 15)  | 
 | 86 | +    g.addEdge(2, 3, 4)  | 
 | 87 | + | 
 | 88 | +    g.kruskals()  | 
 | 89 | + | 
 | 90 | +    # OUTPUT:  | 
 | 91 | +    # Constructed Kruskal's Minimum Spanning Tree:  | 
 | 92 | +    # 2 -> 3 = 4  | 
 | 93 | +    # 0 -> 3 = 5  | 
 | 94 | +    # 0 -> 1 = 10  | 
0 commit comments