kruskal algorithm (kruskal algorithm) detailed explanation

Posted by Addos on Fri, 21 Jan 2022 13:07:59 +0100

kruskal algorithm (kruskal algorithm) detailed explanation

There are two common methods to find the minimum spanning tree in connected networks, which are called prim algorithm and Kruskal algorithm. In this section, we will explain the Kruskal algorithm to you.

The method of Kruskal algorithm to find the minimum spanning tree is to sort all edges in the connected network in ascending order according to the weight size, and select from the edge with the smallest weight. As long as this edge does not form a loop with the selected edge, it can be selected to form the minimum spanning tree. For a connected network with N vertices, N-1 qualified edges are selected, and the spanning tree composed of these edges is the minimum spanning tree.

For example, figure 1 is a connected network. The cruzcar algorithm needs to go through the following steps to find the minimum spanning tree corresponding to figure 1:

Figure 1 connected network

  1. Sort all edges in the connected network in ascending order according to the weight:

  1. Start from the B-D edge. Since no edge has been selected to form the minimum spanning tree, and B-D itself will not form a loop, the B-D edge can form the minimum spanning tree.

Fig. 2 minimum spanning tree composed of B-D edges

  1. The D-T edge will not form a loop with the selected B-D edge, and can form a minimum spanning tree:

Fig. 3 minimum spanning tree composed of D-T edges

  1. A-C edges will not form a loop with the selected B-D and D-T edges, and can form a minimum spanning tree:

Fig. 4 minimum spanning tree composed of a-C edges

  1. The C-D edge will not form a loop with the selected A-C, B-D and D-T edges, and can form a minimum spanning tree:

Fig. 5 minimum spanning tree composed of C-D edges

  1. The C-B edge will form a loop with the selected C-D and B-D edges, so it cannot form a minimum spanning tree:

Fig. 6 C-B edges cannot form a minimum spanning tree

  1. B-T, A-B and S-A will form a loop with the selected A-C, C-D, B-D and D-T, and cannot form a minimum spanning tree. S-A does not form a loop with the selected edges, and can form a minimum spanning tree.

Fig. 7 minimum spanning tree composed of S-A edges

  1. As shown in Figure 7, for a connected network with 6 vertices, we have selected 5 edges, and the spanning tree composed of these edges is the minimum spanning tree.

Fig. 8 minimum spanning tree

Implementation of Kruskal algorithm

The difficulty of realizing Kruskal algorithm is "how to judge whether a new edge will form a loop with the selected edge". Here is a judgment method: in the initial state, configure different markers for each vertex in the connected network. For a new edge, if the marks of the vertices at both ends are different, it will not form a loop and can form a minimum spanning tree. Once the new edge is selected, its two vertices and the vertices at both ends of all the selected edges directly connected to it need to be changed to the same mark; Conversely, if the marks of the vertices at both ends of the new edge are the same, it means that a loop will be formed.

For example, in Figure 4 above, the selected edges are A-c, B-D and d-t. next, it is necessary to judge whether the C-D edges can form A minimum spanning tree. For the selected edge, B-D and D-T are directly adjacent, so the marks of B, D and T are the same (assumed to be 1), and the marks of vertices at both ends of A-C edge are the same (assumed to be 2). Judge whether the C-D edge can form A minimum spanning tree. Because the marks of C and D are different (1 ≠ 2), it can form A minimum spanning tree. C-D is the newly selected edge, and the selected edges connected to it include A-c, B-D and d-t. therefore, A, C, D, B and t should be changed to the same mark.

For another example, judge whether C-B can form a minimum spanning tree based on Fig. 5. According to the analysis results of the above example, the marks of C and B vertices are the same, so the C-B edge will form a loop with other selected edges and cannot form a minimum spanning tree (as shown in Fig. 6).

The following is a C language program for finding the minimum spanning tree in the connected network shown in Figure 1 with Kruskal algorithm:

#include <stdio.h>
#include <stdlib.h>
#define N 9 / / number of edges in the graph
#define P 6 / / number of vertices in the graph
//Construct a structure that represents edges
struct edge {
    //An edge has 2 vertices
    int initial;
    int end;
    //Weight of edge
    int weight;
};
//Used in the qsort sorting function to sort the edges in the edges structure in ascending order according to the weight
int cmp(const void* a, const void* b) {
    return  ((struct edge*)a)->weight - ((struct edge*)b)->weight;
}
//Kruskal algorithm finds the minimum spanning tree, edges stores the edges of the graph entered by the user, and minTree is used to record the edges of the minimum spanning tree
void kruskal_MinTree(struct edge edges[], struct edge minTree[]) {
    int i, initial, end, elem, k;
    //Each vertex is configured with a tag value
    int assists[P];
    int num = 0;
    //In the initial state, the marking of each vertex is different
    for (i = 0; i < P; i++) {
        assists[i] = i;
    }
    //Sort all edges in ascending order according to the weight
    qsort(edges, N, sizeof(edges[0]), cmp);
    //Traverse all edges
    for (i = 0; i < N; i++) {
        //Find the position subscript of the two vertices of the current edge in the assists array
        initial = edges[i].initial - 1;
        end = edges[i].end - 1;
        //If the vertex position exists and the vertex marks are different, it means that it is not in a set and no circuit will be generated
        if (assists[initial] != assists[end]) {
            //Record the edge as part of the minimum spanning tree
            minTree[num] = edges[i];
            //Count + 1
            num++;
            elem = assists[end];
            //Change all the vertex marks newly added to the spanning tree to the same
            for (k = 0; k < P; k++) {
                if (assists[k] == elem) {
                    assists[k] = assists[initial];
                }
            }
            //If the difference between the number of selected edges and the number of vertices is 1, it proves that the minimum spanning tree has been formed and exits the loop
            if (num == P - 1) {
                break;
            }
        }
    }
}
void display(struct edge minTree[]) {
    int cost = 0, i;
    printf("The minimum spanning tree is:\n");
    for (i = 0; i < P - 1; i++) {
        printf("%d-%d  Weight:%d\n", minTree[i].initial, minTree[i].end, minTree[i].weight);
        cost += minTree[i].weight;
    }
    printf("The total weight is:%d", cost);
}
int main() {
    int i;
    struct edge edges[N], minTree[P - 1];
    for (i = 0; i < N; i++) {
        scanf("%d %d %d", &edges[i].initial, &edges[i].end, &edges[i].weight);
    }
    kruskal_MinTree(edges, minTree);
    display(minTree);
    return 0;
}

Java program for finding the minimum spanning tree in the connected network shown in Figure 1 using Kruskal algorithm:

import java.util.Arrays;
import java.util.Scanner;
public class prim {
    static int N = 9; // Number of edges in the graph
    static int P = 6; // Number of vertices in the graph
    //Build a class that represents a path
    public static class edge implements Comparable<edge>{
        //Each path has 2 vertices and 1 weight
        int initial;
        int end;
        int weight;
        public edge(int initial, int end, int weight) {
            this.initial = initial;
            this.end = end;
            this.weight = weight;
        }
        //Sort each edge object in ascending order according to its weight
        @Override
        public int compareTo(edge o) {
            return this.weight - o.weight;
        }
    }
  
    public static void kruskal_MinTree(edge[] edges,edge [] minTree) {
        int []assists = new int[P];
        //Each vertex is configured with a different tag value
        for (int i = 0; i < P; i++) {
            assists[i] = i;
        }
        //Sort all edges in ascending order according to the weight
        Arrays.sort(edges);
        //Traverse all edges
        int num = 0;
        for (int i = 0; i < N; i++) {
            //Find the position subscript of the two vertices of the current edge in the assists array
            int initial = edges[i].initial - 1;
            int end = edges[i].end - 1;
            //If the vertex position exists and the vertex marks are different, it means that it is not in a set and no circuit will be generated
            if (assists[initial] != assists[end]) {
                //Record the edge as part of the minimum spanning tree
                minTree[num] = edges[i];
                //Count + 1
                num++;
                int elem = assists[end];
                //Do not change the vertex markers newly added to the spanning tree to the same
                for (int k = 0; k < P; k++) {
                    if (assists[k] == elem) {
                        assists[k] = assists[initial];
                    }
                }
                //If the difference between the number of selected edges and the number of vertices is 1, it proves that the minimum spanning tree has been formed and exits the loop
                if (num == P - 1) {
                    break;
                }
            }
        }
    }
    public static void display(edge [] minTree) {
        System.out.println("The minimum spanning tree is:");
        int cost = 0;
        for (int i = 0; i < P - 1; i++) {
            System.out.println(minTree[i].initial+" - "+ minTree[i].end+" The weight is:"+minTree[i].weight);
            cost += minTree[i].weight;
        }
        System.out.print("The total weight is:"+cost);
    }
  
    public static void main(String[] args) {
        Scanner scn = new Scanner(System.in);
        edge[] edges = new edge[N];
        edge[] minTree = new edge[P-1];
        System.out.println("Please enter the information of each edge in the figure:");
        for(int i=0;i<N;i++) {
            int initial = scn.nextInt(), end = scn.nextInt(), weight = scn.nextInt();
            edges[i] = new edge(initial,end,weight);
        }
        kruskal_MinTree(edges,minTree);
        display(minTree);
    }
}

Python program for finding the minimum spanning tree in the connected network shown in Figure 1 using Kruskal algorithm:

N = 9   #Number of edges in the graph
P = 6   #Number of vertices in the graph
#Construct a structure that represents edges
class edge:
    #An edge has 2 vertices
    initial = 0
    end = 0
    #Weight of edge
    weight = 0
    def __init__(self,initial,end,weight):
        self.initial = initial
        self.end = end
        self.weight = weight
edges = []   # It is used to save the information of each edge of the graph entered by the user
minTree=[]   # Save the information of each edge of the minimum generation number
#Enter information for N edges
for i in range(N):
    li =  input().split()
    initial = int(li[0])
    end = int(li[1])
    weight = int(li[2])
    edges.append(edge(initial,end,weight))
# Sort the edges list according to weight
def cmp(elem):
    return elem.weight
#Kruskal algorithm for finding minimum spanning tree
def kruskal_MinTree():
    #Record the number of selected edges
    num = 0
    #Configure a different tag for each vertex
    assists = [i for i in range(P)]
    #Sort the edges list
    edges.sort(key = cmp)
    #Traverse N edges and reselect the edges that can form the minimum spanning tree
    for i in range(N):
        #Find the position subscript of the two vertices of the current edge in the assists array
        initial = edges[i].initial -1
        end = edges[i].end-1
        # If the vertex position exists and the vertex marks are different, it means that it is not in a set and no circuit will be generated
        if assists[initial] != assists[end]:
            # Record the edge as part of the minimum spanning tree
            minTree.append(edges[i])
            #Count + 1
            num = num+1
            #Change all the vertex marks newly added to the spanning tree to the same
            elem = assists[end]
            for k in range(P):
                if assists[k] == elem:
                    assists[k]= assists[initial]
            #If the difference between the number of selected edges and the number of vertices is 1, it proves that the minimum spanning tree has been formed and exits the loop
            if num == P-1:
                break
def display():
    cost = 0
    print("The minimum spanning tree is:")
    for i in range(P-1):
        print("%d-%d  Weight:%d"%(minTree[i].initial, minTree[i].end, minTree[i].weight))
        cost = cost + minTree[i].weight
    print("The total weight is:%d"%(cost))
kruskal_MinTree()
display()

The vertices A, B, C, D, S and T in Figure 1 are represented by numbers 1 ~ 6 respectively. The execution results of the above procedures are as follows:

5 1 7
5 3 8
1 2 6
1 3 3
3 2 4
3 4 3
2 4 2
2 6 5
4 6 2

The minimum spanning tree is:

2-4 weight: 2
4-6 weight: 2
1-3 weight: 3
3-4 weight: 3
5-1 weight: 7

Total weight: 17

Topics: Algorithm data structure Graph Theory