public void Constructor()
        {
            var graph      = new AdjacencyGraph <int, Edge <int> >();
            var components = new Dictionary <int, int>();
            var algorithm  = new StronglyConnectedComponentsAlgorithm <int, Edge <int> >(graph);

            AssertAlgorithmProperties(algorithm, graph);

            algorithm = new StronglyConnectedComponentsAlgorithm <int, Edge <int> >(graph, components);
            AssertAlgorithmProperties(algorithm, graph);

            algorithm = new StronglyConnectedComponentsAlgorithm <int, Edge <int> >(null, graph, components);
            AssertAlgorithmProperties(algorithm, graph);

            #region Local function

            void AssertAlgorithmProperties <TVertex, TEdge>(
                StronglyConnectedComponentsAlgorithm <TVertex, TEdge> algo,
                IVertexListGraph <TVertex, TEdge> g)
                where TEdge : IEdge <TVertex>
            {
                AssertAlgorithmState(algo, g);
                Assert.AreEqual(0, algo.ComponentCount);
                CollectionAssert.IsEmpty(algo.Components);
                CollectionAssert.IsEmpty(algo.Graphs);
                CollectionAssert.IsEmpty(algo.Roots);

                Assert.AreEqual(0, algo.Steps);
                Assert.IsNull(algo.VerticesPerStep);
                Assert.IsNull(algo.ComponentsPerStep);
                CollectionAssert.IsEmpty(algo.DiscoverTimes);
            }

            #endregion
        }
        public static IDictionary <int, int> Get(AdjacencyGraph <int, Edge <int> > g)
        {
            var algorithm = new StronglyConnectedComponentsAlgorithm <int, Edge <int> >(g);

            algorithm.Compute();
            return(algorithm.Components);
        }
Beispiel #3
0
        /// <summary>
        /// Search all vertices which are not in a loop.
        ///        /\              /\
        ///       /  \            /  \
        ///      /____\A____C___B/____\
        /// In the above draft, A and B are loops, but C is not.
        /// </summary>
        /// <returns></returns>
        public IEnumerable <CurveVertex> SearchNoneLoopVertices()
        {
            // Find strong connected components
            // https://quickgraph.codeplex.com/wikipage?title=Strongly%20Connected%20Components&referringTitle=User%20Manual

            // A strongly connected component of a graph is a set of vertices such that for each pair u,v of vertices in the component,
            // there exists a path from u to v and v to u.
            // http://stackoverflow.com/questions/6643076/tarjan-cycle-detection-help-c-sharp

            IDictionary <CurveVertex, int> components = new Dictionary <CurveVertex, int>(); //Key: vertex, Value: subgraph index, 0-based.
            var algorithm = new StronglyConnectedComponentsAlgorithm <CurveVertex, SEdge <CurveVertex> >((IVertexListGraph <CurveVertex, SEdge <CurveVertex> >)_graph, components);

            algorithm.Compute();

            var groups = algorithm.Components
                         .GroupBy(x => x.Value, x => x.Key)
                         .Where(x => x.Count() <= 1);
            var result = new List <CurveVertex>();

            foreach (var group in groups)
            {
                result.AddRange(group);
            }
            return(result);
        }
        public static IDictionary <string, int> Get(AdjacencyGraph <string, TaggedEdge <string, string> > g)
        {
            var algorithm = new StronglyConnectedComponentsAlgorithm <string, TaggedEdge <string, string> >(g);

            algorithm.Compute();
            return(algorithm.Components);
        }
        public static BidirectionalGraph <string, TaggedEdge <string, string> >[] GetGraphs(AdjacencyGraph <string, TaggedEdge <string, string> > g)
        {
            var algorithm = new StronglyConnectedComponentsAlgorithm <string, TaggedEdge <string, string> >(g);

            algorithm.Compute();
            return(algorithm.Graphs);
        }
        public void OneComponent()
        {
            var graph = new AdjacencyGraph <int, Edge <int> >();

            graph.AddVerticesAndEdgeRange(new[]
            {
                new Edge <int>(1, 2),
                new Edge <int>(2, 3),
                new Edge <int>(3, 1)
            });

            var algorithm = new StronglyConnectedComponentsAlgorithm <int, Edge <int> >(graph);

            algorithm.Compute();

            Assert.AreEqual(1, algorithm.ComponentCount);
            CollectionAssert.AreEquivalent(
                new Dictionary <int, int>
            {
                [1] = 0,
                [2] = 0,
                [3] = 0
            },
                algorithm.Components);
            Assert.AreEqual(1, algorithm.Graphs.Length);
            CollectionAssert.AreEquivalent(
                new[] { 1, 2, 3 },
                algorithm.Graphs[0].Vertices);
        }
 public void EmptyGraph()
 {
     IVertexListGraph<string, Edge<string>> g = new AdjacencyGraph<string, Edge<string>>(true);
     StronglyConnectedComponentsAlgorithm<string, Edge<String>> strong = new StronglyConnectedComponentsAlgorithm<string, Edge<String>>(g);
     strong.Compute();
     Assert.AreEqual(0, strong.ComponentCount);
     checkStrong(strong);
 }
        private static void Compute <TVertex, TEdge>([NotNull] AdjacencyGraph <TVertex, TEdge> graph)
            where TEdge : IEdge <TVertex>
        {
            var strong = new StronglyConnectedComponentsAlgorithm <TVertex, TEdge>(graph);

            strong.Compute();
            CheckStrong(strong);
        }
        public void MultipleComponents()
        {
            var graph = new AdjacencyGraph <int, Edge <int> >();

            graph.AddVerticesAndEdgeRange(new[]
            {
                new Edge <int>(1, 2),
                new Edge <int>(2, 3),
                new Edge <int>(2, 4),
                new Edge <int>(2, 5),
                new Edge <int>(3, 1),
                new Edge <int>(3, 4),
                new Edge <int>(4, 6),
                new Edge <int>(5, 6),
                new Edge <int>(5, 7),
                new Edge <int>(6, 4),
                new Edge <int>(7, 5),
                new Edge <int>(7, 8),
                new Edge <int>(8, 6),
                new Edge <int>(8, 7)
            });
            graph.AddVertex(10);

            var algorithm = new StronglyConnectedComponentsAlgorithm <int, Edge <int> >(graph);

            algorithm.Compute();

            Assert.AreEqual(4, algorithm.ComponentCount);
            CollectionAssert.AreEquivalent(
                new Dictionary <int, int>
            {
                [1]  = 2,
                [2]  = 2,
                [3]  = 2,
                [4]  = 0,
                [5]  = 1,
                [6]  = 0,
                [7]  = 1,
                [8]  = 1,
                [10] = 3
            },
                algorithm.Components);
            Assert.AreEqual(4, algorithm.Graphs.Length);
            CollectionAssert.AreEquivalent(
                new[] { 4, 6 },
                algorithm.Graphs[0].Vertices);
            CollectionAssert.AreEquivalent(
                new[] { 5, 7, 8 },
                algorithm.Graphs[1].Vertices);
            CollectionAssert.AreEquivalent(
                new[] { 1, 2, 3 },
                algorithm.Graphs[2].Vertices);
            CollectionAssert.AreEquivalent(
                new[] { 10 },
                algorithm.Graphs[3].Vertices);
        }
        public void OneVertex()
        {
            AdjacencyGraph<string, Edge<string>> g = new AdjacencyGraph<string, Edge<string>>(true);
            g.AddVertex("test");
            StronglyConnectedComponentsAlgorithm<string, Edge<String>> strong = new StronglyConnectedComponentsAlgorithm<string, Edge<String>>(g);
            strong.Compute();
            Assert.AreEqual(1, strong.ComponentCount);

            checkStrong(strong);
        }
        public void RunStronglyConnectedComponentsAndCheck <TVertex, TEdge>([NotNull] IVertexListGraph <TVertex, TEdge> graph)
            where TEdge : IEdge <TVertex>
        {
            var algorithm = new StronglyConnectedComponentsAlgorithm <TVertex, TEdge>(graph);

            algorithm.Compute();

            Assert.AreEqual(graph.VertexCount, algorithm.Components.Count);
            Assert.AreEqual(graph.VertexCount, algorithm.Roots.Count);
            Assert.AreEqual(graph.VertexCount, algorithm.DiscoverTimes.Count);
            if (graph.VertexCount == 0)
            {
                Assert.AreEqual(0, algorithm.Steps);
                Assert.IsTrue(algorithm.ComponentCount == 0);
                return;
            }

            Assert.Positive(algorithm.ComponentCount);
            Assert.LessOrEqual(algorithm.ComponentCount, graph.VertexCount);
            foreach (TVertex vertex in algorithm.VisitedGraph.Vertices)
            {
                Assert.IsTrue(algorithm.Components.ContainsKey(vertex));
                Assert.IsTrue(algorithm.DiscoverTimes.ContainsKey(vertex));
            }

            Assert.Positive(algorithm.Steps);
            AssertStepsProperties();
            foreach (KeyValuePair <TVertex, int> pair in algorithm.Components)
            {
                Assert.GreaterOrEqual(pair.Value, 0);
                Assert.IsTrue(pair.Value < algorithm.ComponentCount, $"{pair.Value} < {algorithm.ComponentCount}");
            }

            foreach (KeyValuePair <TVertex, int> time in algorithm.DiscoverTimes)
            {
                Assert.IsNotNull(time.Key);
            }

            foreach (TVertex vertex in graph.Vertices)
            {
                Assert.GreaterOrEqual(algorithm.Components[vertex], 0);
            }

            #region Local function

            void AssertStepsProperties()
            {
                Assert.GreaterOrEqual(algorithm.Steps, 0);
                Assert.AreEqual(algorithm.Steps, algorithm.VerticesPerStep.Count);
                Assert.AreEqual(algorithm.Steps, algorithm.ComponentsPerStep.Count);
            }

            #endregion
        }
        public void EmptyGraph()
        {
            var graph = new AdjacencyGraph <string, Edge <string> >(true);

            var strong = new StronglyConnectedComponentsAlgorithm <string, Edge <string> >(graph);

            strong.Compute();

            Assert.AreEqual(0, strong.ComponentCount);
            CheckStrong(strong);
        }
        public void TwoVertexOnEdge()
        {
            AdjacencyGraph<string, Edge<string>> g = new AdjacencyGraph<string, Edge<string>>(true);
            g.AddVertex("v1");
            g.AddVertex("v2");
            g.AddEdge(new Edge<string>("v1", "v2"));
            StronglyConnectedComponentsAlgorithm<string, Edge<String>> strong = new StronglyConnectedComponentsAlgorithm<string, Edge<String>>(g);
            strong.Compute();
            Assert.AreEqual(2, strong.ComponentCount);

            checkStrong(strong);
        }
        public void OneVertex()
        {
            var graph = new AdjacencyGraph <string, Edge <string> >(true);

            graph.AddVertex("test");

            var strong = new StronglyConnectedComponentsAlgorithm <string, Edge <string> >(graph);

            strong.Compute();

            Assert.AreEqual(1, strong.ComponentCount);
            CheckStrong(strong);
        }
        public void TwoVertexOnEdge()
        {
            var graph = new AdjacencyGraph <string, Edge <string> >(true);

            graph.AddVertex("v1");
            graph.AddVertex("v2");
            graph.AddEdge(new Edge <string>("v1", "v2"));

            var strong = new StronglyConnectedComponentsAlgorithm <string, Edge <string> >(graph);

            strong.Compute();

            Assert.AreEqual(2, strong.ComponentCount);
            CheckStrong(strong);
        }
        private int ComputeComponentCount(Dictionary <TVertex, int> components)
        {
            IConnectedComponentAlgorithm <TVertex, TEdge, IVertexListGraph <TVertex, TEdge> > componentAlgorithm;

            if (this.StronglyConnected)
            {
                componentAlgorithm = new StronglyConnectedComponentsAlgorithm <TVertex, TEdge>(
                    this,
                    this.VisitedGraph,
                    components);
            }
            else
            {
                componentAlgorithm = new WeaklyConnectedComponentsAlgorithm <TVertex, TEdge>(
                    this,
                    this.VisitedGraph,
                    components);
            }
            componentAlgorithm.Compute();
            return(componentAlgorithm.ComponentCount);
        }
        private static void CheckStrong <TVertex, TEdge>([NotNull] StronglyConnectedComponentsAlgorithm <TVertex, TEdge> algorithm)
            where TEdge : IEdge <TVertex>
        {
            Assert.AreEqual(algorithm.VisitedGraph.VertexCount, algorithm.Components.Count);
            Assert.AreEqual(algorithm.VisitedGraph.VertexCount, algorithm.DiscoverTimes.Count);
            Assert.AreEqual(algorithm.VisitedGraph.VertexCount, algorithm.Roots.Count);

            foreach (TVertex vertex in algorithm.VisitedGraph.Vertices)
            {
                Assert.IsTrue(algorithm.Components.ContainsKey(vertex));
                Assert.IsTrue(algorithm.DiscoverTimes.ContainsKey(vertex));
            }

            foreach (KeyValuePair <TVertex, int> component in algorithm.Components)
            {
                Assert.IsNotNull(component.Key);
                Assert.IsTrue(component.Value <= algorithm.ComponentCount);
            }

            foreach (KeyValuePair <TVertex, int> time in algorithm.DiscoverTimes)
            {
                Assert.IsNotNull(time.Key);
            }
        }
        public void RegularLattice()
        {
            IVertexListGraph<string, Edge<string>> g = new AdjacencyGraphFactory().RegularLattice10x10();
            StronglyConnectedComponentsAlgorithm<string, Edge<String>> strong = new StronglyConnectedComponentsAlgorithm<string, Edge<String>>(g);

            strong.Compute();
            checkStrong(strong);
        }
        public void FileDependency()
        {
            IVertexListGraph<string, Edge<string>> g = new AdjacencyGraphFactory().FileDependency();
            StronglyConnectedComponentsAlgorithm<string, Edge<String>> strong = new StronglyConnectedComponentsAlgorithm<string, Edge<String>>(g);

            strong.Compute();
            checkStrong(strong);
        }
        private void checkStrong(StronglyConnectedComponentsAlgorithm<string, Edge<String>> strong)
        {
            Assert.AreEqual(strong.VisitedGraph.VertexCount, strong.Components.Count);
            Assert.AreEqual(strong.VisitedGraph.VertexCount, strong.DiscoverTimes.Count);
            Assert.AreEqual(strong.VisitedGraph.VertexCount, strong.Roots.Count);

            foreach (string v in strong.VisitedGraph.Vertices)
            {
                Assert.IsTrue(strong.Components.ContainsKey(v));
                Assert.IsTrue(strong.DiscoverTimes.ContainsKey(v));
            }

            foreach (KeyValuePair<string,int> de in strong.Components)
            {
                Assert.IsNotNull(de.Key);
                Assert.LowerEqualThan(de.Value, strong.ComponentCount);
            }

            foreach (KeyValuePair<string,int> de in strong.DiscoverTimes)
            {
                Assert.IsNotNull(de.Key);
            }
        }