|  | 
|  | 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