Пример #1
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
        }
Пример #2
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
        }
Пример #3
0
        /// <summary>
        /// Gets a copy of the connected components. Key is the number of components,
        /// Value contains the vertex -> component index map.
        /// </summary>
        /// <returns>Number of components associated to components vertex mapping.</returns>
        public KeyValuePair <int, IDictionary <TVertex, int> > GetComponents()
        {
            if (_sets is null)
            {
                throw new InvalidOperationException("Run the algorithm before.");
            }

            var representatives = new Dictionary <TVertex, int>(_sets.SetCount);

            if (_components is null)
            {
                _components = new Dictionary <TVertex, int>(VisitedGraph.VertexCount);
            }
            foreach (TVertex vertex in VisitedGraph.Vertices)
            {
                TVertex representative = _sets.FindSet(vertex);
                // ReSharper disable once AssignNullToNotNullAttribute, Justification: All graph vertices are in a set
                if (!representatives.TryGetValue(representative, out int index))
                {
                    representatives[representative] = index = representatives.Count;
                }
                _components[vertex] = index;
            }

            Debug.Assert(_sets.SetCount == ComponentCount);
            Debug.Assert(_components.Count == VisitedGraph.VertexCount);
            return(new KeyValuePair <int, IDictionary <TVertex, int> >(_sets.SetCount, _components));
        }
        /// <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);
        }
        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);
        }