/// <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 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 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 static IDictionary <int, int> Get(AdjacencyGraph <int, Edge <int> > g) { var algorithm = new StronglyConnectedComponentsAlgorithm <int, Edge <int> >(g); algorithm.Compute(); return(algorithm.Components); }
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 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); }
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); }
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); }