Implement Kruskals Algorithm in Golang



In this article we are going to understand how to develop a golang program to implement kruskals Algorithm with the help of union-find Algorithm and priority queue approach. Kruskal's Algorithm is used to find the minimum spanning tree of a graph.

Algorithm

  • Step 1 ? First, we need to import the fmt and sort packages. Then create structures called Edge, graph and subset and assign properties to it.

  • Step 2 ? Then sort all the edges of the graph in non-decreasing order of their weight.

  • Step 3 ? Create a disjoint set data structure, where each set contains only one vertex.

  • Step 4 ? For each edge in the sorted graph. If the edge connects two disjoint sets then we need to add it to the minimum spanning tree and merge the two sets. At last return the minimum spanning tree.

  • Step 5 ? Now, start the main() function. Inside the main() function initialize a graph and assign edges to it. Further call the kruskals() function by passing the edge as argument to it.

  • Step 6 ? Store the result obtained by the function in a variable and print them on the screen.

Example 1

In this Example we will write a go language program to implement Kruskals Algorithm by using union-find Algorithm.

Open Compiler
package main import ( "fmt" "sort" ) type Edge struct { Src, Dest, Weight int } type Graph struct { Edges []Edge Vertices int } type Subset struct { Parent int Rank int } func find(subsets []Subset, i int) int { if subsets[i].Parent != i { subsets[i].Parent = find(subsets, subsets[i].Parent) } return subsets[i].Parent } func union(subsets []Subset, x, y int) { rootX := find(subsets, x) rootY := find(subsets, y) if subsets[rootX].Rank < subsets[rootY].Rank { subsets[rootX].Parent = rootY } else if subsets[rootX].Rank > subsets[rootY].Rank { subsets[rootY].Parent = rootX } else { subsets[rootY].Parent = rootX subsets[rootX].Rank++ } } func kruskals(graph Graph) []Edge { sortedEdges := make([]Edge, len(graph.Edges)) copy(sortedEdges, graph.Edges) sort.Slice(sortedEdges, func(i, j int) bool { return sortedEdges[i].Weight < sortedEdges[j].Weight }) subsets := make([]Subset, graph.Vertices) for i := range subsets { subsets[i].Parent = i subsets[i].Rank = 0 } result := make([]Edge, 0, graph.Vertices-1) for _, edge := range sortedEdges { srcRoot := find(subsets, edge.Src) destRoot := find(subsets, edge.Dest) if srcRoot != destRoot { result = append(result, edge) union(subsets, srcRoot, destRoot) } } return result } func main() { graph := Graph{ Edges: []Edge{ {0, 1, 10}, {0, 2, 6}, {0, 3, 5}, {1, 3, 15}, {2, 3, 4}, }, Vertices: 4, } fmt.Println("The given input is:", graph) fmt.Println() mst := kruskals(graph) fmt.Println("Minimum Spanning Tree:") for _, edge := range mst { fmt.Printf("(%d, %d) with weight %d\n", edge.Src, edge.Dest, edge.Weight) } }

Output

The given input is: {[{0 1 10} {0 2 6} {0 3 5} {1 3 15} {2 3 4}] 4}

Minimum Spanning Tree:
(2, 3) with weight 4
(0, 3) with weight 5
(0, 1) with weight 10

Example 2

In this Example we will write a go language program to implement the kruskals Algorithm by using the priority queue Algorithm.

Open Compiler
package main import ( "container/heap" "fmt" ) type Edge struct { Src int Dest int Weight int } type Graph struct { Edges []Edge Vertices int } type PriorityQueue []*Item type Item struct { value Edge priority int index int } func (pq PriorityQueue) Len() int { return len(pq) } func (pq PriorityQueue) Less(i, j int) bool { return pq[i].priority < pq[j].priority } func (pq PriorityQueue) Swap(i, j int) { pq[i], pq[j] = pq[j], pq[i] pq[i].index = i pq[j].index = j } func (pq *PriorityQueue) Push(x interface{}) { n := len(*pq) item := x.(*Item) item.index = n *pq = append(*pq, item) } func (pq *PriorityQueue) Pop() interface{} { old := *pq n := len(old) item := old[n-1] item.index = -1 // for safety *pq = old[0 : n-1] return item } func find(subsets []int, i int) int { if subsets[i] != i { subsets[i] = find(subsets, subsets[i]) } return subsets[i] } func union(subsets []int, x int, y int) { xroot := find(subsets, x) yroot := find(subsets, y) subsets[yroot] = xroot } func kruskals(graph Graph) []Edge { pq := make(PriorityQueue, len(graph.Edges)) for i, edge := range graph.Edges { pq[i] = &Item{ value: edge, priority: edge.Weight, index: i, } } heap.Init(&pq) subsets := make([]int, graph.Vertices) for i := range subsets { subsets[i] = i } result := make([]Edge, 0, graph.Vertices-1) for pq.Len() > 0 { item := heap.Pop(&pq).(*Item) edge := item.value srcRoot := find(subsets, edge.Src) destRoot := find(subsets, edge.Dest) if srcRoot != destRoot { result = append(result, edge) // Update the parent node of the subset containing the src vertex union(subsets, edge.Src, edge.Dest) } } return result } func main() { graph := Graph{ Edges: []Edge{ {0, 1, 10}, {0, 2, 6}, {0, 3, 5}, {1, 3, 15}, {2, 3, 4}, }, Vertices: 4, } fmt.Println("The given input is:", graph) mst := kruskals(graph) fmt.Println() fmt.Println("Minimum Spanning Tree:") for _, edge := range mst { fmt.Printf("(%d, %d) with weight %d\n", edge.Src, edge.Dest, edge.Weight) } }

Output

The given input is: {[{0 1 10} {0 2 6} {0 3 5} {1 3 15} {2 3 4}] 4}

Minimum Spanning Tree:
(2, 3) with weight 4
(0, 3) with weight 5
(0, 1) with weight 10

Conclusion

We have successfully compiled and executed a go language program to implement the Kruskal's Algorithm along with Examples.

Updated on: 2023-04-05T15:20:06+05:30

366 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements