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>();

            foreach (Edge e in 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.DeleteMin();
                int  v = e.Either;
                int  w = e.other(v);
                if (!uf.Connected(v, w))
                { // v-w does not create a cycle
                  // merge v and w components
                    uf.Union(v, w);
                    mst.Enqueue(e); // add edge e to mst
                    weight += e.Weight;
                }
            }

            // check optimality conditions
            //assert ;
            Contract.Assert(check(G));
        }
Beispiel #2
0
        /**
         * Compute a minimum spanning tree (or forest) of an edge-weighted graph.
         * @param G the edge-weighted graph
         */
        public BoruvkaMST(EdgeWeightedGraph G)
        {
            UF uf = new UF(G.V);

            // repeat at most log V times or until we have V-1 edges
            for (int t = 1; t < G.V && mst.Count < 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()
                Edge[] closest = new Edge[G.V];
                foreach (Edge 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 || e < closest[i])
                    {
                        closest[i] = e;
                    }
                    if (closest[j] == null || e < closest[j])
                    {
                        closest[j] = e;
                    }
                }

                // add newly discovered edges to MST
                for (int i = 0; i < G.V; i++)
                {
                    Edge 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);
            Contract.Assert(check(G));
        }
Beispiel #3
0
        public void OptimalAlgorithm_UF_StepByStep_Tuples()
        {
            UF uF = new UF(10);


            for (int i = 0; i < 10; i++)
            {
                int p = tuples[i, 0];
                int q = tuples[i, 1];
                if (!uF.Connected(p, q))
                {
                    uF.Union(p, q);
                }

                switch (i)
                {
                case 0:
                    Assert.True(uF.Connected(4, 3));
                    Assert.Equal(4, uF.Ids[3]);
                    Assert.Equal(1, uF.Ranks[4]);
                    Assert.Equal(0, uF.Ranks[3]);
                    break;

                case 1:
                    Assert.True(uF.Connected(8, 3));
                    Assert.True(uF.Connected(8, 4));
                    Assert.Equal(4, uF.Ids[3]);
                    Assert.Equal(4, uF.Ids[8]);
                    Assert.Equal(1, uF.Ranks[4]);
                    Assert.Equal(0, uF.Ranks[8]);
                    break;

                case 2:
                    Assert.True(uF.Connected(6, 5));
                    Assert.Equal(6, uF.Ids[5]);
                    Assert.Equal(1, uF.Ranks[6]);
                    Assert.Equal(0, uF.Ranks[5]);
                    break;

                case 3:
                    Assert.True(uF.Connected(4, 9));
                    Assert.Equal(4, uF.Ids[9]);
                    Assert.Equal(1, uF.Ranks[4]);
                    Assert.Equal(0, uF.Ranks[9]);
                    break;

                case 4:
                    Assert.True(uF.Connected(2, 1));
                    Assert.Equal(2, uF.Ids[1]);
                    Assert.Equal(1, uF.Ranks[2]);
                    Assert.Equal(0, uF.Ranks[1]);
                    break;

                case 5:
                    Assert.True(uF.Connected(8, 9));
                    Assert.Equal(4, uF.Ids[9]);
                    Assert.Equal(4, uF.Ids[8]);
                    break;

                case 6:
                    Assert.True(uF.Connected(5, 0));
                    Assert.Equal(6, uF.Ids[5]);
                    Assert.Equal(6, uF.Ids[0]);
                    break;

                case 7:
                    Assert.True(uF.Connected(7, 2));
                    Assert.Equal(2, uF.Ids[7]);
                    break;

                case 8:
                    Assert.True(uF.Connected(6, 1));
                    Assert.Equal(6, uF.Ids[1]);
                    Assert.Equal(2, uF.Ranks[6]);
                    break;

                case 9:
                    Assert.True(uF.Connected(7, 3));
                    Assert.Equal(6, uF.Ids[4]);
                    Assert.Equal(6, uF.Ids[7]);
                    Assert.Equal(6, uF.Ids[3]);
                    break;

                default: break;
                }
            }

            // at the end
            Assert.Equal(new byte[] { 0, 0, 1, 0, 1, 0, 2, 0, 0, 0 }, uF.Ranks);
            Assert.Equal(new[] { 6, 6, 6, 6, 6, 6, 6, 6, 4, 4 }, uF.Ids);
            Assert.Equal(1, uF.Count);
        }