コード例 #1
0
        public void Test1()
        {
            ArrayDisjointSet <int> Disj = new ArrayDisjointSet <int>();

            Disj.CreateSet(3); Disj.CreateSet(4);
            Disj.Join(4, 3);
            WriteLine($"{Disj.GetRepresentative(3)}; {Disj.GetRepresentative(4)}");
        }
コード例 #2
0
        /// <summary>
        ///     Try and join K-Minimum Spanning Tree such that all connected components are
        ///     having a size less than the given threshold.
        ///     TODO: Test this more carefully.
        /// </summary>
        public virtual void KMinKruskal()
        {
            // mapping integer representative to the partition size.
            IDictionary <int, int> ComponentSizes = new SortedDictionary <int, int>();

            // Disjoint set for kruskal.
            IDisjointSet <Point> ds = new ArrayDisjointSet <Point>();

            SortedSet <Edge> ChosenEdges = new SortedSet <Edge>();

            // Maping Component's rerepsentative to partitions of type PointCollection.
            SortedDictionary <int, PointCollection> Partitions = new SortedDictionary <int, PointCollection>();

            // A set of set of points, each represents all vertices that are in the same component.
            SortedSet <PointCollection> ClustersSet = new SortedSet <PointCollection>();

            for (int I = 0; I < Idx_V.Count; I++)
            {
                ds.CreateSet(Idx_V[I]);
                ComponentSizes[I] = 1; // Integer representative starts indexing from 1.
                PointCollection pc = new PointCollection(Idx_V[I]);
                Partitions[I] = pc;
                ClustersSet.Add(pc);
            }

            foreach (Edge e in E)
            {
                Point u = e.a, v = e.b;
                if (ds.FindSet(u) == ds.FindSet(v))
                {
                    continue;
                }
                int JoinedSize = ComponentSizes[ds.FindSet(u) - 1] + ComponentSizes[ds.FindSet(v) - 1];
                if (JoinedSize > Threshold)
                {
                    continue;
                }
                PointCollection P1 = Partitions[ds.FindSet(v) - 1], P2 = Partitions[ds.FindSet(u) - 1];
                PointCollection JoinedPartition = P1 + P2;
                ds.Join(u, v);
                ComponentSizes[ds.FindSet(u) - 1] = JoinedSize;
                Partitions[ds.FindSet(u) - 1]     = JoinedPartition;
                ClustersSet.Remove(P1);
                ClustersSet.Remove(P2);
                ClustersSet.Add(JoinedPartition);
                ChosenEdges.Add(e);
            }
            ChosenE     = ChosenEdges;
            KComponents = ClustersSet;
        }
コード例 #3
0
        /// <summary>
        /// Run Kruskal and establish the boolean edges selection.
        /// * return the size of max partition while running the kruskal.
        /// </summary>
        /// <returns>
        /// Max Partitions.
        /// </returns>
        protected virtual IList <int> EstablishMST()
        {
            // A list of maximum size for each iteration.
            IList <int> MaxSize = new List <int>();

            // Disjoint set for kruskal.
            IDisjointSet <Point> ds = new ArrayDisjointSet <Point>();

            // Keep track of max partition.
            SortedSet <int> CompSizes = new SortedSet <int>();

            // mapping integer representative to the partition size.
            IDictionary <int, int> PartitionSizes = new SortedDictionary <int, int>();

            for (int I = 0; I < V.Count; I++)
            {
                ds.CreateSet(V[I]);
                PartitionSizes[I] = 1; // Integer representative starts indexing from 1.
            }

            SortedSet <Edge> ChosenEdges = new SortedSet <Edge>();

            MaxSize.Add(1);
            int TotalComponentCount = V.Count - 1;

            foreach (Edge e in E)
            {
                Point u = e.a, v = e.b;
                if (ds.FindSet(u) != ds.FindSet(v))
                {
                    int MergedSize = PartitionSizes[ds.FindSet(u) - 1] + PartitionSizes[ds.FindSet(v) - 1];
                    ds.Join(u, v);
                    PartitionSizes[ds.FindSet(u) - 1] = MergedSize;
                    CompSizes.Add(MergedSize);
                    ChosenEdges.Add(e);
                    --TotalComponentCount;
                }

                MaxSize.Add(CompSizes.Max);
                if (TotalComponentCount == 0)
                {
                    break;
                }
            }

            // Establish Field.
            ChosenE = ChosenEdges;
            return(MaxSize);
        }
コード例 #4
0
        public void TestDisjointSetBasic()
        {
            IDisjointSet <int> d = new ArrayDisjointSet <int>();

            for (int i = 0; ++i <= 4;)
            {
                d.CreateSet(i);
            }
            d.Join(3, 4);
            Assert.IsTrue(d.GetRepresentative(3) == 3);
            Assert.IsTrue(d.GetRepresentative(4) == 3);
            d.Join(3, 2);
            Assert.AreEqual(d.FindSet(3), d.FindSet(2));
            Assert.AreEqual(d.FindSet(2), d.FindSet(4));
            d.Join(2, 4);
            TestDelegate dele = () =>
            {
                d.Join(2, 5);
            };

            AssertThrowException <InvalidArgumentException>(dele);
        }
コード例 #5
0
        /// <summary>
        ///     * Run Kruskal again with the information about the max breaking edge
        ///     in the graph.
        /// </summary>
        protected virtual SortedSet <PointCollection> KrusktalAagain()
        {
            int TerminateIndex          = base.IdentifyMaxBreakingEdge();
            ArrayDisjointSet <Point> ds = new ArrayDisjointSet <Point>();
            SortedDictionary <int, PointCollection> Partitions  = new SortedDictionary <int, PointCollection>();
            SortedSet <PointCollection>             ClustersSet = new SortedSet <PointCollection>();

            for (int I = 0; I < V.Count; I++)
            {
                ds.CreateSet(V[I]);
                PointCollection pc = new PointCollection(V[I]);
                Partitions[I] = pc;
                ClustersSet.Add(pc);
            }

            foreach (Edge e in E)
            {
                Point v = e.a, u = e.b;
                if (ChosenE.Contains(e))
                {
                    PointCollection P1 = Partitions[ds.FindSet(v) - 1], P2 = Partitions[ds.FindSet(u) - 1];
                    PointCollection JoinedPartition = P1 + P2;
                    ds.Join(v, u);
                    Partitions[ds.FindSet(u) - 1] = JoinedPartition;
                    ClustersSet.Remove(P1);
                    ClustersSet.Remove(P2);
                    ClustersSet.Add(JoinedPartition);
                }
                if (--TerminateIndex == 1)
                {
                    break;                        // Gives it some room.
                }
            }

            return(ClustersSet);
        }