Minimum Spanning Tree—Kruskal Algorithm

What is a minimum spanning tree?
First of all, the minimum spanning tree must be an undirected graph, and without affecting the connectivity of all points, what is the minimum value of the weights of all edges.
For example: the undirected graph abcp is shown in the figure below, and the weight of each edge is also marked. The minimum spanning tree is shown on the right.
insert image description here
Of course, all points can be connected without the edge of 1 and 2, but it is not the smallest.

Kruskal Algorithm
The idea of ​​using Kruskal to generate the smallest tree can be generally summarized as: greedy algorithm + union search idea.

  1. Check all the edges, from the edge with small weight to the edge with heavy weight (greedy).
  2. The current edge enters the minimum spanning tree set and is either kept or discarded.
  3. If the current edge will not form a loop, keep the current edge; if it will form a loop, don't use the current edge.
  4. After the inspection, the minimum spanning tree set is completed.
    Still use the abcp diagram above as an example:
    check from small to large, and the edge with weight 1 is connected to AC, and will not form a ring, so keep it.
    The edge with weight 2 is connected to BC and will not form a ring, so it is reserved.
    The edge with weight 3 is connected to CP and will not form a ring, so keep it.
    The edge with a weight of 100 is connected to AB. At this time, ABC forms a ring. If it is not used, the same is true for the AP edge, forming the final minimum tree.
    So how to check the ring? At this time, it is used and checked. If you don’t understand, it is recommended to read and check the introduction and principle first .

Code implementation
Sort the weights of Edges through the small root heap, the small ones are at the top of the heap, and then pop up to see if the from and to nodes of the edge are in the same set in the union search set. If it is not there, it is union, and if it is there, it means that there is a ring.

public static class UnionFind {
    
    
        HashMap<Node, Integer> sizeMap;
        HashMap<Node, Node> parent;

        public UnionFind() {
    
    
            sizeMap = new HashMap<>();
            parent = new HashMap<>();
        }

        public void makeSets(Collection<Node> nodes) {
    
    
            sizeMap.clear();
            ;
            parent.clear();

            for (Node cur : nodes) {
    
    
                sizeMap.put(cur, 1);
                parent.put(cur, cur);
            }
        }

        public Node findParent(Node cur) {
    
    
            Stack<Node> stack = new Stack<>();
            while (cur != parent.get(cur)) {
    
    
                stack.add(cur);
                cur = parent.get(cur);
            }

            while (!stack.isEmpty()) {
    
    
                parent.put(stack.pop(), cur);
            }
            return cur;
        }

        public boolean isSameSet(Node a, Node b) {
    
    
            return findParent(a) == findParent(b);
        }

        public void union(Node a, Node b) {
    
    
            if (a == null || b == null) {
    
    
                return;
            }
            Node aNode = findParent(a);
            Node bNode = findParent(b);

            if (aNode != bNode) {
    
    
                int aSize = sizeMap.get(aNode);
                int bSize = sizeMap.get(bNode);

                if (aSize >= bSize) {
    
    
                    parent.put(bNode, aNode);
                    sizeMap.put(aNode, aSize + bSize);
                    sizeMap.remove(bNode);
                } else {
    
    
                    parent.put(aNode, bNode);
                    sizeMap.put(aNode, aSize + bSize);
                    sizeMap.remove(aNode);
                }
            }
        }
    }
    
    public static class MyComparator implements Comparator<Edge>{
    
    

        @Override
        public int compare(Edge o1, Edge o2) {
    
    
            return o1.weight - o2.weight;
        }
    }

    public static Set<Edge> kruskalMST(Graph graph) {
    
    
        UnionFind uf = new UnionFind();
        uf.makeSets(graph.nodes.values());
        
        PriorityQueue<Edge> heap = new PriorityQueue(new MyComparator());
        for (Edge edge : graph.edges){
    
    
            heap.add(edge);
        }

        Set<Edge> result = new HashSet<>();
        
        while (!heap.isEmpty()){
    
    
            Edge edge = heap.poll();
            while (!uf.isSameSet(edge.from,edge.to)){
    
    
                uf.union(edge.from,edge.to);
                result.add(edge);
            }
        }
        return result;
    }

Guess you like

Origin blog.csdn.net/weixin_43936962/article/details/132221071
Recommended