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)}"); }
/// <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; }
/// <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); }
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); }
/// <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); }