/*public static IEnumerable<IMutableVertexAndEdgeListGraph<TVertex, TEdge>> StronglyConnectedComponents<TVertex, TEdge>(this IVertexListGraph<TVertex, TEdge> g, Func<IMutableVertexAndEdgeListGraph<TVertex, TEdge>> componentMaker) * where TEdge : QuickGraph.IEdge<TVertex> * { * g.StronglyConnectedComponents(out var scc); * * return scc.GroupBy(kv => kv.Value).Select(group => * { * var c = componentMaker(); * * group.ForEach(kv => c.AddVertex(kv.Key)); * * foreach (var v1 in c.Vertices) * foreach (var v2 in c.Vertices) * { * if (g.TryGetEdges(v1, v2, out var edges)) * edges.ForEach(e => c.AddEdge(e)); * } * }); * }*/ /// <summary> /// Returns the list of weakly connected components in a graph. A weakly connected component is one in which /// <list type="number"> /// <item>for every pair of vertices V,W, W is reachable from V, ignoring edge-direction, and </item> /// <item>one cannot add another node U such that the first property still holds.</item> /// </list> /// </summary> /// <typeparam name="TGraph">The type of the produced components.</typeparam> /// <typeparam name="TVertex">The type of the vertices.</typeparam> /// <typeparam name="TEdge">The type of the edges.</typeparam> /// <param name="g">The graph.</param> /// <param name="componentMaker">A producer-function for empty empty components.</param> public static IList <TGraph> WeaklyConnectedComponents <TGraph, TVertex, TEdge>(this GraphBase <TVertex, TEdge> g, Func <TGraph> componentMaker) where TEdge : class, IEdge <TVertex> where TGraph : GraphBase <TVertex, TEdge> { var undirected = new NonDirectedGraph <TVertex, NonDirectedEdge <TVertex> >(); g.Vertices.ForEach(undirected.Add); g.Edges.ForEach(e => undirected.Add(new NonDirectedEdge <TVertex>(e.StartVertex, e.EndVertex))); var subgraphs = new List <TGraph>(); //Find the subgraphs (connected components that are candidates for being turned into trees). var dcGraphFinder = new DisconnectedGraphsFinder <TVertex, NonDirectedEdge <TVertex> >( () => new SubGraphView <TVertex, NonDirectedEdge <TVertex> >(undirected), undirected); dcGraphFinder.FindDisconnectedGraphs(); foreach (var component in dcGraphFinder.FoundDisconnectedGraphs) { var subG = componentMaker(); component.Vertices.ForEach(subG.Add); foreach (var v1 in component.Vertices) { foreach (var v2 in component.Vertices) { g.GetEdges(v1, v2).ForEach(subG.Add); } } subgraphs.Add(subG); } return(subgraphs); }
public void BasicDepthFirstSearchCrawlerTest() { // create example graph, non-directed. NonDirectedGraph <string, NonDirectedEdge <string> > graph = new NonDirectedGraph <string, NonDirectedEdge <string> >(); // create edges. simply use string literals, which will point to the same vertices anyway. graph.Add(new NonDirectedEdge <string>("A", "B")); graph.Add(new NonDirectedEdge <string>("A", "C")); graph.Add(new NonDirectedEdge <string>("A", "G")); graph.Add(new NonDirectedEdge <string>("A", "F")); graph.Add(new NonDirectedEdge <string>("F", "D")); graph.Add(new NonDirectedEdge <string>("F", "E")); graph.Add(new NonDirectedEdge <string>("D", "E")); graph.Add(new NonDirectedEdge <string>("E", "G")); graph.Add(new NonDirectedEdge <string>("H", "I")); graph.Add(new NonDirectedEdge <string>("J", "K")); graph.Add(new NonDirectedEdge <string>("J", "L")); graph.Add(new NonDirectedEdge <string>("J", "M")); graph.Add(new NonDirectedEdge <string>("L", "M")); DepthFirstSearchTester <string, NonDirectedEdge <string> > dfs = new DepthFirstSearchTester <string, NonDirectedEdge <string> >(graph); dfs.Start(); Assert.AreEqual(13, dfs.VerticesLoggedInOnVisiting.Count); Assert.AreEqual(13, dfs.VerticesLoggedInOnVisited.Count); // visual confirmation logging code Console.Write("Vertices logged in order by OnVisiting:\n\t"); foreach (string v in dfs.VerticesLoggedInOnVisiting) { Console.Write(v + " "); } Console.Write("\n\nVertices logged in order by OnVisited:\n\t"); foreach (string v in dfs.VerticesLoggedInOnVisited) { Console.Write(v + " "); } // start in another tree in the graph dfs.VerticesLoggedInOnVisited.Clear(); dfs.VerticesLoggedInOnVisiting.Clear(); dfs.Start("L"); Assert.AreEqual(13, dfs.VerticesLoggedInOnVisiting.Count); Assert.AreEqual(13, dfs.VerticesLoggedInOnVisited.Count); Console.Write("\n\nVertices logged in order by OnVisiting:\n\t"); foreach (string v in dfs.VerticesLoggedInOnVisiting) { Console.Write(v + " "); } Console.Write("\n\nVertices logged in order by OnVisited:\n\t"); foreach (string v in dfs.VerticesLoggedInOnVisited) { Console.Write(v + " "); } }