zoukankan      html  css  js  c++  java
  • Kruskal算法

    1.算法简单描述

    1).记Graph中有v个顶点,e个边

    2).新建图Graphnew,Graphnew中拥有原图中相同的e个顶点,但没有边

    3).将原图Graph中所有e个边按权值从小到大排序

    4).循环:从权值最小的边开始遍历每条边 直至图Graph中所有的节点都在同一个连通分量中

                    if 这条边连接的两个节点于图Graphnew中不在同一个连通分量中

                                             添加这条边到图Graphnew

    public class KruskalMST {
        private static final double FLOATING_POINT_EPSILON = 1E-12;
    
        private double weight;                        // weight of MST
        private Queue<Edge> mst = new Queue<Edge>();  // edges in MST
    
        /**
         * Compute a minimum spanning tree (or forest) of an edge-weighted graph.
         * @param G the edge-weighted graph
         */
        public KruskalMST(EdgeWeightedGraph G) {
            // more efficient to build heap by passing array of edges
            MinPQ<Edge> pq = new MinPQ<Edge>();
            for (Edge e : G.edges()) {
                pq.insert(e);
            }
    
            // run greedy algorithm
            UF uf = new UF(G.V());
            while (!pq.isEmpty() && mst.size() < G.V() - 1) {
                Edge e = pq.delMin();
                int v = e.either();
                int w = e.other(v);
                if (uf.find(v) != uf.find(w)) { // v-w does not create a cycle
                    uf.union(v, w);  // merge v and w components
                    mst.enqueue(e);  // add edge e to mst
                    weight += e.weight();
                }
            }
    
            // check optimality conditions
            assert check(G);
        }
    
        /**
         * Returns the edges in a minimum spanning tree (or forest).
         * @return the edges in a minimum spanning tree (or forest) as
         *    an iterable of edges
         */
        public Iterable<Edge> edges() {
            return mst;
        }
    
        /**
         * Returns the sum of the edge weights in a minimum spanning tree (or forest).
         * @return the sum of the edge weights in a minimum spanning tree (or forest)
         */
        public double weight() {
            return weight;
        }
        
        // check optimality conditions (takes time proportional to E V lg* V)
        private boolean check(EdgeWeightedGraph G) {
    
            // check total weight
            double total = 0.0;
            for (Edge e : edges()) {
                total += e.weight();
            }
            if (Math.abs(total - weight()) > FLOATING_POINT_EPSILON) {
                System.err.printf("Weight of edges does not equal weight(): %f vs. %f
    ", total, weight());
                return false;
            }
    
            // check that it is acyclic
            UF uf = new UF(G.V());
            for (Edge e : edges()) {
                int v = e.either(), w = e.other(v);
                if (uf.find(v) == uf.find(w)) {
                    System.err.println("Not a forest");
                    return false;
                }
                uf.union(v, w);
            }
    
            // check that it is a spanning forest
            for (Edge e : G.edges()) {
                int v = e.either(), w = e.other(v);
                if (uf.find(v) != uf.find(w)) {
                    System.err.println("Not a spanning forest");
                    return false;
                }
            }
    
            // check that it is a minimal spanning forest (cut optimality conditions)
            for (Edge e : edges()) {
    
                // all edges in MST except e
                uf = new UF(G.V());
                for (Edge f : mst) {
                    int x = f.either(), y = f.other(x);
                    if (f != e) uf.union(x, y);
                }
                
                // check that e is min weight edge in crossing cut
                for (Edge f : G.edges()) {
                    int x = f.either(), y = f.other(x);
                    if (uf.find(x) != uf.find(y)) {
                        if (f.weight() < e.weight()) {
                            System.err.println("Edge " + f + " violates cut optimality conditions");
                            return false;
                        }
                    }
                }
    
            }
    
            return true;
        }
    
    
        /**
         * Unit tests the {@code KruskalMST} data type.
         *
         * @param args the command-line arguments
         */
        public static void main(String[] args) {
            In in = new In(args[0]);
            EdgeWeightedGraph G = new EdgeWeightedGraph(in);
            KruskalMST mst = new KruskalMST(G);
            for (Edge e : mst.edges()) {
                StdOut.println(e);
            }
            StdOut.printf("%.5f
    ", mst.weight());
        }
    
    }
  • 相关阅读:
    leetcode 75 颜色分类 A
    leetcode525连续数组 A
    WCF无身份验证配置
    三读设计模式
    EntityFrameWork+Oracle学习笔记搭配环境(一)
    EntityFrameWork+Oracle学习笔记DBfirst(二)
    用Python解答百度测试开发算法面试题
    Python实现采集wordpress整站数据的爬虫
    吾八哥学Python(六):运算符与表达式
    吾八哥学Python(四):了解Python基础语法(下)
  • 原文地址:https://www.cnblogs.com/hequnwang/p/14331100.html
Copyright © 2011-2022 走看看