protected override void InternalCompute()
        {
            var cancelManager = this.Services.CancelManager;
            var ds = new ForestDisjointSet<TVertex>(this.VisitedGraph.VertexCount);
            foreach (var v in this.VisitedGraph.Vertices)
                ds.MakeSet(v);

            if (cancelManager.IsCancelling)
                return;

            var queue = new BinaryQueue<TEdge, double>(this.edgeWeights);
            foreach (var e in this.VisitedGraph.Edges)
                queue.Enqueue(e);

            if (cancelManager.IsCancelling)
                return;

            while (queue.Count > 0)
            {
                var e = queue.Dequeue();
                this.OnExamineEdge(e);
                if (!ds.AreInSameSet(e.Source, e.Target))
                {
                    this.OnTreeEdge(e);
                    ds.Union(e.Source, e.Target);
                }
            }
        }
Beispiel #2
0
        public void Union_Throws()
        {
            var vertex  = new TestVertex("1");
            var vertex2 = new TestVertex("2");
            var set     = new ForestDisjointSet <TestVertex>();

            // ReSharper disable ReturnValueOfPureMethodIsNotUsed
            // ReSharper disable AssignNullToNotNullAttribute
            Assert.Throws <ArgumentNullException>(() => set.Union(vertex, null));
            Assert.Throws <ArgumentNullException>(() => set.Union(null, vertex));
            Assert.Throws <ArgumentNullException>(() => set.Union(null, null));
            // ReSharper restore AssignNullToNotNullAttribute

            Assert.Throws <KeyNotFoundException>(() => set.Union(vertex, vertex));
            Assert.Throws <KeyNotFoundException>(() => set.Union(vertex, vertex2));
            Assert.Throws <KeyNotFoundException>(() => set.Union(vertex2, vertex));
            Assert.Throws <KeyNotFoundException>(() => set.Union(vertex2, vertex2));

            set.MakeSet(vertex);
            Assert.DoesNotThrow(() => set.Union(vertex, vertex));
            Assert.Throws <KeyNotFoundException>(() => set.Union(vertex, vertex2));
            Assert.Throws <KeyNotFoundException>(() => set.Union(vertex2, vertex));
            Assert.Throws <KeyNotFoundException>(() => set.Union(vertex2, vertex2));
            // ReSharper restore ReturnValueOfPureMethodIsNotUsed
        }
Beispiel #3
0
        /// <inheritdoc />
        protected override void InternalCompute()
        {
            _sets = new ForestDisjointSet <TVertex>(VisitedGraph.VertexCount);

            // Initialize one set per vertex
            foreach (TVertex vertex in VisitedGraph.Vertices)
            {
                _sets.MakeSet(vertex);
            }

            // Join existing edges
            foreach (TEdge edge in VisitedGraph.Edges)
            {
                _sets.Union(edge.Source, edge.Target);
            }

            // Hook to graph event
            if (_hooked)
            {
                return;
            }

            VisitedGraph.EdgeAdded     += OnEdgeAdded;
            VisitedGraph.EdgeRemoved   += OnEdgeRemoved;
            VisitedGraph.VertexAdded   += OnVertexAdded;
            VisitedGraph.VertexRemoved += OnVertexRemoved;

            _hooked = true;
        }
Beispiel #4
0
        public void Contains()
        {
            ContainsTest(1, 2);
            ContainsTest(
                new TestVertex("1"),
                new TestVertex("2"));
            ContainsTest(
                new EquatableTestVertex("1"),
                new EquatableTestVertex("2"));

            #region Local function

            void ContainsTest <TValue>(TValue value1, TValue value2)
            {
                var set = new ForestDisjointSet <TValue>();

                Assert.IsFalse(set.Contains(value1));
                Assert.IsFalse(set.Contains(value2));

                set.MakeSet(value1);
                Assert.IsTrue(set.Contains(value1));
                Assert.IsFalse(set.Contains(value2));

                set.MakeSet(value2);
                Assert.IsTrue(set.Contains(value1));
                Assert.IsTrue(set.Contains(value2));

                set.Union(value1, value2);
                Assert.IsTrue(set.Contains(value1));
                Assert.IsTrue(set.Contains(value2));
            }

            #endregion
        }
        /// <inheritdoc />
        protected override void InternalCompute()
        {
            var sets = new ForestDisjointSet <TVertex>(VisitedGraph.VertexCount);

            foreach (TVertex vertex in VisitedGraph.Vertices)
            {
                sets.MakeSet(vertex);
            }

            ThrowIfCancellationRequested();

            var queue = new BinaryQueue <TEdge, double>(_edgeWeights);

            foreach (TEdge edge in VisitedGraph.Edges)
            {
                queue.Enqueue(edge);
            }

            ThrowIfCancellationRequested();

            while (queue.Count > 0)
            {
                TEdge edge = queue.Dequeue();
                OnExamineEdge(edge);

                if (!sets.AreInSameSet(edge.Source, edge.Target))
                {
                    OnTreeEdge(edge);
                    sets.Union(edge.Source, edge.Target);
                }
            }
        }
Beispiel #6
0
        public void FindSet()
        {
            FindSetTest(1, 2);
            FindSetTest(
                new TestVertex("1"),
                new TestVertex("2"));
            FindSetTest(
                new EquatableTestVertex("1"),
                new EquatableTestVertex("2"));

            #region Local function

            void FindSetTest <TValue>(TValue value1, TValue value2)
            {
                var set = new ForestDisjointSet <TValue>();

                AssertSetSizes(set, 0, 0);

                set.MakeSet(value1);
                AssertSetSizes(set, 1, 1);
                AssertEqual(value1, set.FindSet(value1));

                set.MakeSet(value2);
                AssertSetSizes(set, 2, 2);
                AssertEqual(value1, set.FindSet(value1));
                AssertEqual(value2, set.FindSet(value2));

                set.Union(value1, value2);
                AssertSetSizes(set, 1, 2);
                AssertEqual(value1, set.FindSet(value1));
                AssertEqual(value1, set.FindSet(value2));
            }

            #endregion
        }
        protected static UndirectedGraph <string, TaggedEdge <string, double> > GetUndirectedCompleteGraph(int vertex)
        {
            var random    = new Random();
            var graph     = new UndirectedGraph <string, TaggedEdge <string, double> >();
            var trueGraph = new UndirectedGraph <string, TaggedEdge <string, double> >();
            var sets      = new ForestDisjointSet <string>(vertex);

            for (int i = 0; i < vertex; ++i)
            {
                graph.AddVertex(i.ToString());
                trueGraph.AddVertex(i.ToString());
                sets.MakeSet(i.ToString());
            }

            for (int i = 0; i < vertex; ++i)
            {
                for (int j = i + 1; j < vertex; ++j)
                {
                    graph.AddEdge(
                        new TaggedEdge <string, double>(
                            i.ToString(),
                            j.ToString(),
                            random.Next(100)));
                }
            }

            return(graph);
        }
        public void Unions(int elementCount, [PexAssumeNotNull]KeyValuePair<int,int>[] unions)
        {
            PexAssume.IsTrue(0 < elementCount);
            PexSymbolicValue.Minimize(elementCount);
            PexAssume.TrueForAll(
                unions, 
                u => 0 <= u.Key && u.Key < elementCount && 
                     0 <= u.Value && u.Value < elementCount
                     );

            var target = new ForestDisjointSet<int>();
            // fill up with 0..elementCount - 1
            for (int i = 0; i < elementCount; i++)
            {
                target.MakeSet(i);
                Assert.IsTrue(target.Contains(i));
                Assert.AreEqual(i + 1, target.ElementCount);
                Assert.AreEqual(i + 1, target.SetCount);
            }

            // apply Union for pairs unions[i], unions[i+1]
            for (int i = 0; i < unions.Length; i++)
            {
                var left = unions[i].Key;
                var right= unions[i].Value;

                var setCount = target.SetCount;
                bool unioned = target.Union(left, right);
                // should be in the same set now
                Assert.IsTrue(target.AreInSameSet(left, right));
                // if unioned, the count decreased by 1
                PexAssert.ImpliesIsTrue(unioned, () => setCount - 1 == target.SetCount);
            }
        }
Beispiel #9
0
 private static void AssertSetSizes <T>(
     [NotNull] ForestDisjointSet <T> set,
     int expectedSetCount,
     int expectedCount)
 {
     Assert.AreEqual(expectedSetCount, set.SetCount);
     Assert.AreEqual(expectedCount, set.ElementCount);
 }
Beispiel #10
0
        public void Contains_Throws()
        {
            var set = new ForestDisjointSet <TestVertex>();

            // ReSharper disable once ReturnValueOfPureMethodIsNotUsed
            // ReSharper disable once AssignNullToNotNullAttribute
            Assert.Throws <ArgumentNullException>(() => set.Contains(null));
        }
Beispiel #11
0
        public void FindSet_Throws()
        {
            var vertex = new TestVertex();
            var set    = new ForestDisjointSet <TestVertex>();

            // ReSharper disable ReturnValueOfPureMethodIsNotUsed
            // ReSharper disable once AssignNullToNotNullAttribute
            Assert.Throws <ArgumentNullException>(() => set.FindSet(null));
            Assert.Throws <KeyNotFoundException>(() => set.FindSet(vertex));
            // ReSharper restore ReturnValueOfPureMethodIsNotUsed
        }
Beispiel #12
0
        public void MakeSet_Throws()
        {
            var testObject = new TestVertex();
            var set        = new ForestDisjointSet <TestVertex>();

            // ReSharper disable once AssignNullToNotNullAttribute
            Assert.Throws <ArgumentNullException>(() => set.MakeSet(null));

            set.MakeSet(testObject);
            // Double insert
            Assert.Throws <ArgumentException>(() => set.MakeSet(testObject));
        }
 public static ForestDisjointSet<int> Create(int[] elements, int[] unions)
 {
     var ds = new ForestDisjointSet<int>();
     for (int i = 0; i < elements.Length; ++i)
         ds.MakeSet(i);
     for (int i = 0; i+1 < unions.Length; i+=2)
     {
         PexAssume.IsTrue(ds.Contains(unions[i]));
         PexAssume.IsTrue(ds.Contains(unions[i+1]));
         ds.Union(unions[i], unions[i+1]);
     }
     return ds;
 }
        /// <inheritdoc />
        protected override void InternalCompute()
        {
            if (!TryGetRootVertex(out TVertex root))
            {
                throw new InvalidOperationException("Root vertex not set.");
            }
            if (_pairs is null)
            {
                throw new InvalidProgramException("Pairs not set.");
            }

            var graph             = _pairs.ToAdjacencyGraph();
            var disjointSet       = new ForestDisjointSet <TVertex>();
            var verticesAncestors = new Dictionary <TVertex, TVertex>();
            var dfs = new DepthFirstSearchAlgorithm <TVertex, TEdge>(
                this,
                VisitedGraph,
                new Dictionary <TVertex, GraphColor>(VisitedGraph.VertexCount));

            dfs.InitializeVertex += vertex => disjointSet.MakeSet(vertex);
            dfs.DiscoverVertex   += vertex => verticesAncestors[vertex] = vertex;
            dfs.TreeEdge         += edge =>
            {
                disjointSet.Union(edge.Source, edge.Target);
                // ReSharper disable once AssignNullToNotNullAttribute
                // Justification: must be in the set because unioned just before.
                verticesAncestors[disjointSet.FindSet(edge.Source)] = edge.Source;
            };
            dfs.FinishVertex += vertex =>
            {
                foreach (SEquatableEdge <TVertex> edge in graph.OutEdges(vertex))
                {
                    if (dfs.VerticesColors[edge.Target] == GraphColor.Black)
                    {
                        SEquatableEdge <TVertex> pair = edge.ToVertexPair();
                        // ReSharper disable once AssignNullToNotNullAttribute
                        // Justification: must be present in the set.
                        Ancestors[pair] = verticesAncestors[disjointSet.FindSet(edge.Target)];
                    }
                }
            };

            // Run DFS
            dfs.Compute(root);
        }
        public static ForestDisjointSet <int> Create([NotNull] int[] elements, [NotNull] int[] unions)
        {
            var sets = new ForestDisjointSet <int>();

            for (int i = 0; i < elements.Length; ++i)
            {
                sets.MakeSet(i);
            }

            for (int i = 0; i + 1 < unions.Length; i += 2)
            {
                Assert.IsTrue(sets.Contains(unions[i]));
                Assert.IsTrue(sets.Contains(unions[i + 1]));
                sets.Union(unions[i], unions[i + 1]);
            }

            return(sets);
        }
        public static IDisjointSet <TVertex> ComputeDisjointSet <TVertex, TEdge>(this IUndirectedGraph <TVertex, TEdge> visitedGraph)
            where TEdge : IEdge <TVertex>
        {
            Contract.Requires(visitedGraph != null);

            var ds = new ForestDisjointSet <TVertex>(visitedGraph.VertexCount);

            foreach (var v in visitedGraph.Vertices)
            {
                ds.MakeSet(v);
            }
            foreach (var e in visitedGraph.Edges)
            {
                ds.Union(e.Source, e.Target);
            }

            return(ds);
        }
        protected override void InternalCompute()
        {
            var cancelManager = this.Services.CancelManager;

            TVertex root;

            if (!this.TryGetRootVertex(out root))
            {
                throw new InvalidOperationException("root vertex not set");
            }
            if (this.pairs == null)
            {
                throw new InvalidOperationException("pairs not set");
            }

            var gpair       = GraphExtensions.ToAdjacencyGraph(this.pairs);
            var disjointSet = new ForestDisjointSet <TVertex>();
            var vancestors  = new Dictionary <TVertex, TVertex>();
            var dfs         = new DepthFirstSearchAlgorithm <TVertex, TEdge>(this, this.VisitedGraph, new Dictionary <TVertex, GraphColor>(this.VisitedGraph.VertexCount));

            dfs.InitializeVertex += v => disjointSet.MakeSet(v);
            dfs.DiscoverVertex   += v => vancestors[v] = v;
            dfs.TreeEdge         += edge =>
            {
                disjointSet.Union(edge.Source, edge.Target);
                vancestors[disjointSet.FindSet(edge.Source)] = edge.Source;
            };
            dfs.FinishVertex += v =>
            {
                foreach (var e in gpair.OutEdges(v))
                {
                    if (dfs.VertexColors[e.Target] == GraphColor.Black)
                    {
                        this.ancestors[EdgeExtensions.ToVertexPair <TVertex, SEquatableEdge <TVertex> >(e)] = vancestors[disjointSet.FindSet(e.Target)];
                    }
                }
            };

            // go!
            dfs.Compute(root);
        }
Beispiel #18
0
        protected override void InternalCompute()
        {
            this.ds = new ForestDisjointSet <TVertex>(this.VisitedGraph.VertexCount);
            // initialize 1 set per vertex
            foreach (var v in this.VisitedGraph.Vertices)
            {
                this.ds.MakeSet(v);
            }

            // join existing edges
            foreach (var e in this.VisitedGraph.Edges)
            {
                this.ds.Union(e.Source, e.Target);
            }

            // unhook/hook to graph event
            this.VisitedGraph.EdgeAdded     += new EdgeAction <TVertex, TEdge>(VisitedGraph_EdgeAdded);
            this.VisitedGraph.EdgeRemoved   += new EdgeAction <TVertex, TEdge>(VisitedGraph_EdgeRemoved);
            this.VisitedGraph.VertexAdded   += new VertexAction <TVertex>(VisitedGraph_VertexAdded);
            this.VisitedGraph.VertexRemoved += new VertexAction <TVertex>(VisitedGraph_VertexRemoved);
        }
        /// <inheritdoc />
        protected override void InternalCompute()
        {
            ICancelManager cancelManager = Services.CancelManager;

            var sets = new ForestDisjointSet <TVertex>(VisitedGraph.VertexCount);

            foreach (TVertex vertex in VisitedGraph.Vertices)
            {
                sets.MakeSet(vertex);
            }

            if (cancelManager.IsCancelling)
            {
                return;
            }

            var queue = new BinaryQueue <TEdge, double>(_edgeWeights);

            foreach (TEdge edge in VisitedGraph.Edges)
            {
                queue.Enqueue(edge);
            }

            if (cancelManager.IsCancelling)
            {
                return;
            }

            while (queue.Count > 0)
            {
                TEdge edge = queue.Dequeue();
                OnExamineEdge(edge);

                if (!sets.AreInSameSet(edge.Source, edge.Target))
                {
                    OnTreeEdge(edge);
                    sets.Union(edge.Source, edge.Target);
                }
            }
        }
        private void InitializeVerticesToEdges()
        {
            _verticesEdges   = new Dictionary <TVertex, HashSet <TEdge> >();
            _visitedVertices = new HashSet <TVertex>();
            _sets            = new ForestDisjointSet <TVertex>(VisitedGraph.VertexCount);

            foreach (TVertex vertex in VisitedGraph.Vertices)
            {
                if (_visitedVertices.Count == 0)
                {
                    _visitedVertices.Add(vertex);
                }

                _sets.MakeSet(vertex);
                _verticesEdges.Add(vertex, new HashSet <TEdge>());
            }

            foreach (TEdge edge in VisitedGraph.Edges)
            {
                _verticesEdges[edge.Source].Add(edge);
                _verticesEdges[edge.Target].Add(edge);
            }
        }
Beispiel #21
0
        private void Unions(int elementCount, [NotNull] KeyValuePair <int, int>[] unions)
        {
            Assert.IsTrue(0 < elementCount);
            QuikGraphAssert.TrueForAll(
                unions,
                u => 0 <= u.Key &&
                u.Key < elementCount &&
                0 <= u.Value &&
                u.Value < elementCount);

            var target = new ForestDisjointSet <int>();

            // Fill up with 0..elementCount - 1
            for (int i = 0; i < elementCount; ++i)
            {
                target.MakeSet(i);
                Assert.IsTrue(target.Contains(i));
                Assert.AreEqual(i + 1, target.ElementCount);
                Assert.AreEqual(i + 1, target.SetCount);
            }

            // Apply Union for pairs unions[i], unions[i+1]
            foreach (KeyValuePair <int, int> pair in unions)
            {
                int left  = pair.Key;
                int right = pair.Value;

                int  setCount = target.SetCount;
                bool unioned  = target.Union(left, right);

                // Should be in the same set now
                Assert.IsTrue(target.AreInSameSet(left, right));

                // If unioned, the count decreased by 1
                QuikGraphAssert.ImpliesIsTrue(unioned, () => setCount - 1 == target.SetCount);
            }
        }
        private UndirectedGraph <string, TaggedEdge <string, double> > GetUndirectedFullGraph(int vert)
        {
            Console.WriteLine("Start");
            var usedEdge  = new List <KeyValuePair <int, int> >();
            var random    = new Random();
            var graph     = new UndirectedGraph <string, TaggedEdge <string, double> >();
            var trueGraph = new UndirectedGraph <string, TaggedEdge <string, double> >();
            var ds        = new ForestDisjointSet <string>(vert);

            for (int i = 0; i < vert; i++)
            {
                graph.AddVertex(i.ToString());
                trueGraph.AddVertex(i.ToString());
                ds.MakeSet(i.ToString());
            }
            for (int i = 0; i < vert; i++)
            {
                for (int j = i + 1; j < vert; j++)
                {
                    graph.AddEdge(new TaggedEdge <string, double>(i.ToString(), j.ToString(), random.Next(100)));
                }
            }
            return(graph);
        }
Beispiel #23
0
        public void AreInSameSet()
        {
            AreInSameSetTest(1, 2);
            AreInSameSetTest(
                new TestVertex("1"),
                new TestVertex("2"));
            AreInSameSetTest(
                new EquatableTestVertex("1"),
                new EquatableTestVertex("2"));

            #region Local function

            void AreInSameSetTest <TValue>(TValue value1, TValue value2)
            {
                var set = new ForestDisjointSet <TValue>();

                AssertSetSizes(set, 0, 0);

                set.MakeSet(value1);
                Assert.IsTrue(set.AreInSameSet(value1, value1));

                set.MakeSet(value2);
                Assert.IsTrue(set.AreInSameSet(value1, value1));
                Assert.IsFalse(set.AreInSameSet(value1, value2));
                Assert.IsFalse(set.AreInSameSet(value2, value1));
                Assert.IsTrue(set.AreInSameSet(value2, value2));

                set.Union(value1, value2);
                Assert.IsTrue(set.AreInSameSet(value1, value1));
                Assert.IsTrue(set.AreInSameSet(value1, value2));
                Assert.IsTrue(set.AreInSameSet(value2, value1));
                Assert.IsTrue(set.AreInSameSet(value2, value2));
            }

            #endregion
        }
        protected override void InternalCompute()
        {
            var dic           = new Dictionary <TVertex, HashSet <TEdge> >();
            var cancelManager = this.Services.CancelManager;
            var visetedVert   = new HashSet <TVertex>();
            var edges         = new HashSet <TEdge>();
            var queue         = new BinaryQueue <TEdge, double>(this.edgeWeights);
            var ds            = new ForestDisjointSet <TVertex>(this.VisitedGraph.VertexCount);

            foreach (var v in this.VisitedGraph.Vertices)
            {
                if (visetedVert.Count == 0)
                {
                    visetedVert.Add(v);
                }
                ds.MakeSet(v);
                dic.Add(v, new HashSet <TEdge>());
            }
            foreach (var e in this.VisitedGraph.Edges)
            {
                dic[e.Source].Add(e);
                dic[e.Target].Add(e);
            }

            if (cancelManager.IsCancelling)
            {
                return;
            }
            var enumerator = visetedVert.GetEnumerator();

            enumerator.MoveNext();
            var lastVert = enumerator.Current;

            foreach (var edge in dic[lastVert])
            {
                if (!edges.Contains(edge))
                {
                    edges.Add(edge);
                    queue.Enqueue(edge);
                }
            }
            if (cancelManager.IsCancelling)
            {
                return;
            }

            while (edges.Count > 0 && visetedVert.Count < VisitedGraph.VertexCount)
            {
                var mined = queue.Dequeue();
                this.OnExamineEdge(mined);
                if (!ds.AreInSameSet(mined.Source, mined.Target))
                {
                    this.OnTreeEdge(mined);
                    ds.Union(mined.Source, mined.Target);
                    if (visetedVert.Contains(mined.Source))
                    {
                        lastVert = mined.Target;
                        visetedVert.Add(mined.Target);
                    }
                    else
                    {
                        lastVert = mined.Source;
                        visetedVert.Add(mined.Source);
                    }
                    foreach (var edge in dic[lastVert])
                    {
                        if (!edges.Contains(edge))
                        {
                            edges.Add(edge);
                            queue.Enqueue(edge);
                        }
                    }
                }
            }
        }
Beispiel #25
0
        protected override void InternalCompute()
        {
            var cancelManager = this.Services.CancelManager;
            var visetedVert   = new List <TVertex>();
            var visetedEdges  = new List <TEdge>();
            var ds            = new ForestDisjointSet <TVertex>(this.VisitedGraph.VertexCount);

            foreach (var v in this.VisitedGraph.Vertices)
            {
                if (visetedVert.Count == 0)
                {
                    visetedVert.Add(v);
                }
                ds.MakeSet(v);
            }

            if (cancelManager.IsCancelling)
            {
                return;
            }

            var queue = new BinaryQueue <TEdge, double>(this.edgeWeights);

            foreach (var edge in this.VisitedGraph.Edges)
            {
                if (!visetedEdges.Contains(edge) && (visetedVert.Contains(edge.Source) || visetedVert.Contains(edge.Target)))
                {
                    queue.Enqueue(edge);
                    visetedEdges.Add(edge);
                }
            }

            if (cancelManager.IsCancelling)
            {
                return;
            }

            while (queue.Count > 0)
            {
                foreach (var edge in this.VisitedGraph.Edges)
                {
                    if (!visetedEdges.Contains(edge) && (visetedVert.Contains(edge.Source) || visetedVert.Contains(edge.Target)))
                    {
                        queue.Enqueue(edge);
                        visetedEdges.Add(edge);
                    }
                }
                var e = queue.Dequeue();
                this.OnExamineEdge(e);
                if (!ds.AreInSameSet(e.Source, e.Target))
                {
                    this.OnTreeEdge(e);
                    ds.Union(e.Source, e.Target);
                    if (visetedVert.Contains(e.Source))
                    {
                        visetedVert.Add(e.Target);
                    }
                    else
                    {
                        visetedVert.Add(e.Source);
                    }
                }
            }
        }
Beispiel #26
0
        public void Union()
        {
            UnionTest(1, 2, 3, 4, 5);
            UnionTest(
                new TestVertex("1"),
                new TestVertex("2"),
                new TestVertex("3"),
                new TestVertex("4"),
                new TestVertex("5"));
            UnionTest(
                new EquatableTestVertex("1"),
                new EquatableTestVertex("2"),
                new EquatableTestVertex("3"),
                new EquatableTestVertex("4"),
                new EquatableTestVertex("5"));

            #region Local function

            void UnionTest <TValue>(
                TValue value1,
                TValue value2,
                TValue value3,
                TValue value4,
                TValue value5)
            {
                ForestDisjointSet <TValue> set = MakeAndFillSet();

                set.Union(value1, value2);
                AssertSetSizes(set, 4, 5);
                Assert.IsTrue(set.AreInSameSet(value1, value2));

                set.Union(value4, value3);
                AssertSetSizes(set, 3, 5);
                Assert.IsTrue(set.AreInSameSet(value3, value4));

                set.Union(value1, value4);
                AssertSetSizes(set, 2, 5);
                Assert.IsTrue(set.AreInSameSet(value1, value2));
                Assert.IsTrue(set.AreInSameSet(value1, value3));
                Assert.IsTrue(set.AreInSameSet(value1, value4));

                set.Union(value1, value5);
                AssertSetSizes(set, 1, 5);
                Assert.IsTrue(set.AreInSameSet(value1, value2));
                Assert.IsTrue(set.AreInSameSet(value1, value3));
                Assert.IsTrue(set.AreInSameSet(value1, value4));
                Assert.IsTrue(set.AreInSameSet(value1, value5));

                // Already merged
                set.Union(value1, value1);
                AssertSetSizes(set, 1, 5);
                Assert.IsTrue(set.AreInSameSet(value1, value2));
                Assert.IsTrue(set.AreInSameSet(value1, value3));
                Assert.IsTrue(set.AreInSameSet(value1, value4));
                Assert.IsTrue(set.AreInSameSet(value1, value5));

                set.Union(value1, value4);
                AssertSetSizes(set, 1, 5);
                Assert.IsTrue(set.AreInSameSet(value1, value2));
                Assert.IsTrue(set.AreInSameSet(value1, value3));
                Assert.IsTrue(set.AreInSameSet(value1, value4));
                Assert.IsTrue(set.AreInSameSet(value1, value5));

                set.Union(value4, value1);
                AssertSetSizes(set, 1, 5);
                Assert.IsTrue(set.AreInSameSet(value1, value2));
                Assert.IsTrue(set.AreInSameSet(value1, value3));
                Assert.IsTrue(set.AreInSameSet(value1, value4));
                Assert.IsTrue(set.AreInSameSet(value1, value5));


                set = MakeAndFillSet();
                set.Union(value1, value2);
                AssertSetSizes(set, 4, 5);
                Assert.IsTrue(set.AreInSameSet(value1, value2));

                set.Union(value2, value4);
                AssertSetSizes(set, 3, 5);
                Assert.IsTrue(set.AreInSameSet(value1, value2));
                Assert.IsTrue(set.AreInSameSet(value1, value4));

                set.Union(value5, value2);
                AssertSetSizes(set, 2, 5);
                Assert.IsTrue(set.AreInSameSet(value1, value2));
                Assert.IsTrue(set.AreInSameSet(value1, value4));
                Assert.IsTrue(set.AreInSameSet(value1, value5));

                #region Local function

                ForestDisjointSet <TValue> MakeAndFillSet()
                {
                    var s = new ForestDisjointSet <TValue>();

                    s.MakeSet(value1);
                    s.MakeSet(value2);
                    s.MakeSet(value3);
                    s.MakeSet(value4);
                    s.MakeSet(value5);
                    AssertSetSizes(s, 5, 5);

                    return(s);
                }

                #endregion
            }

            #endregion
        }