Ejemplo n.º 1
0
        private readonly Collections.Queue <EdgeW> _mst = new Collections.Queue <EdgeW>(); // edges in MST

        /// <summary>
        /// Compute a minimum spanning tree (or forest) of an edge-weighted graph.
        /// </summary>
        /// <param name="g">g the edge-weighted graph</param>
        public KruskalMST(EdgeWeightedGraph g)
        {
            // more efficient to build heap by passing array of edges
            var pq = new MinPQ <EdgeW>();

            foreach (var e in g.Edges())
            {
                pq.Insert(e);
            }

            // run greedy algorithm
            var uf = new UF(g.V);

            while (!pq.IsEmpty() && _mst.Size() < g.V - 1)
            {
                var e = pq.DelMin();
                var v = e.Either();
                var w = e.Other(v);
                if (!uf.Connected(v, 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);
        }
Ejemplo n.º 2
0
        private readonly double _weight;                       // weight of MST

        /// <summary>
        /// Compute a minimum spanning tree (or forest) of an edge-weighted graph.
        /// </summary>
        /// <param name="g">g the edge-weighted graph</param>
        public BoruvkaMST(EdgeWeightedGraph g)
        {
            var uf = new UF(g.V);

            // repeat at most log V times or until we have V-1 edges
            for (var t = 1; t < g.V && _mst.Size() < g.V - 1; t = t + t)
            {
                // foreach tree in forest, find closest edge
                // if edge weights are equal, ties are broken in favor of first edge in G.edges()
                var closest = new EdgeW[g.V];
                foreach (var e in g.Edges())
                {
                    int v = e.Either(), w = e.Other(v);
                    int i = uf.Find(v), j = uf.Find(w);
                    if (i == j)
                    {
                        continue;           // same tree
                    }
                    if (closest[i] == null || Less(e, closest[i]))
                    {
                        closest[i] = e;
                    }
                    if (closest[j] == null || Less(e, closest[j]))
                    {
                        closest[j] = e;
                    }
                }

                // add newly discovered edges to MST
                for (var i = 0; i < g.V; i++)
                {
                    var e = closest[i];
                    if (e != null)
                    {
                        int v = e.Either(), w = e.Other(v);
                        // don't add the same edge twice
                        if (!uf.Connected(v, w))
                        {
                            _mst.Add(e);
                            _weight += e.Weight;
                            uf.Union(v, w);
                        }
                    }
                }
            }

            // check optimality conditions
            //assert check(G);
        }
Ejemplo n.º 3
0
        private UF Union(Tuple <int, int>[] links, int N)
        {
            UF uf = new UF(N);

            foreach (var pair in links)
            {
                int p = pair.Item1;
                int q = pair.Item2;
                if (uf.Connected(p, q))
                {
                    continue;
                }
                uf.Union(pair.Item1, pair.Item2);
            }
            return(uf);
        }
Ejemplo n.º 4
0
        public KruskalMST(EdgeWeightedGraph g)
        {
            _mst = new Queue <Edge>();
            var pq = new MinPQ <Edge>(g.E);

            foreach (var e in g.Edges())
            {
                pq.Insert(e);
            }
            var uf = new UF(g.V);

            while (!pq.IsEmpty && _mst.Count < g.V - 1)
            {
                var e = (Edge)pq.DeleteMin();
                int v = e.Either(), w = e.Other(v);
                if (uf.Connected(v, w))
                {
                    continue;
                }
                uf.Union(v, w);
                _mst.Enqueue(e);
            }
        }
Ejemplo n.º 5
0
        public KruskalMST(IEdgeWeightGraph G)
        {
            mst = new Chapter1.Queue <IEdge>();
            MinPQ <IEdge> pq = new MinPQ <IEdge>();

            foreach (var e in G.Edges())
            {
                pq.Insert(e);
            }
            UF uf = new UF(G.V);

            while (!pq.IsEmpty && mst.Size < G.V - 1)
            {
                IEdge e = pq.Delete();  //找到权重最小的边
                int   v = e.Either, w = e.Other(v);
                if (uf.Connected(v, w)) //忽略失效的边
                {
                    continue;
                }
                uf.Union(v, w);
                mst.Enqueue(e);
            }
        }
Ejemplo n.º 6
0
        /// <summary>
        /// check optimality conditions (takes time proportional to E V lg* V)
        /// </summary>
        /// <param name="g"></param>
        /// <returns></returns>
        public bool Check(EdgeWeightedGraph g)
        {
            // check total weight
            var total = Edges().Sum(e => e.Weight);

            if (Math.Abs(total - Weight()) > FLOATING_POINT_EPSILON)
            {
                Console.Error.WriteLine($"Weight of edges does not equal weight(): {total} vs. {Weight()}{Environment.NewLine}");
                return(false);
            }

            // check that it is acyclic
            var uf = new UF(g.V);

            foreach (var e in Edges())
            {
                int v = e.Either(), w = e.Other(v);
                if (uf.Connected(v, w))
                {
                    Console.Error.WriteLine("Not a forest");
                    return(false);
                }
                uf.Union(v, w);
            }

            // check that it is a spanning forest
            foreach (var e in g.Edges())
            {
                int v = e.Either(), w = e.Other(v);
                if (!uf.Connected(v, w))
                {
                    Console.Error.WriteLine("Not a spanning forest");
                    return(false);
                }
            }

            // check that it is a minimal spanning forest (cut optimality conditions)
            foreach (var e in Edges())
            {
                // all edges in MST except e
                uf = new UF(g.V);
                foreach (var f in _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
                foreach (var f in g.Edges())
                {
                    int x = f.Either(), y = f.Other(x);
                    if (!uf.Connected(x, y))
                    {
                        if (f.Weight < e.Weight)
                        {
                            Console.Error.WriteLine($"Edge {f}  violates cut optimality conditions");
                            return(false);
                        }
                    }
                }
            }

            return(true);
        }