public void FindDisconnectedSubGraphsTest() { SimpleGraph <string, Edge <string> > graph = new SimpleGraph <string, Edge <string> >(false); graph.Add(new Edge <string>("A", "B", false)); // A->B graph.Add(new Edge <string>("A", "C", false)); // A->C graph.Add(new Edge <string>("B", "D", false)); // B->D graph.Add(new Edge <string>("C", "D", false)); // C->D graph.Add(new Edge <string>("D", "E", false)); // D->E graph.Add(new Edge <string>("G", "F", false)); // G->F, different subgraph Assert.IsFalse(graph.IsConnected()); DisconnectedGraphsFinder <string, Edge <string> > finder = new DisconnectedGraphsFinder <string, Edge <string> >( () => new SubGraphView <string, Edge <string> >(graph), graph); finder.FindDisconnectedGraphs(); Assert.AreEqual(2, finder.FoundDisconnectedGraphs.Count); Assert.AreEqual(5, finder.FoundDisconnectedGraphs[0].Vertices.Count()); Assert.AreEqual(2, finder.FoundDisconnectedGraphs[1].Vertices.Count()); Assert.AreEqual(5, finder.FoundDisconnectedGraphs[0].Edges.Count()); Assert.AreEqual(1, finder.FoundDisconnectedGraphs[1].Edges.Count()); finder.FindDisconnectedGraphs("A", true); Assert.AreEqual(1, finder.FoundDisconnectedGraphs.Count); Assert.AreEqual(5, finder.FoundDisconnectedGraphs[0].Vertices.Count()); Assert.AreEqual(5, finder.FoundDisconnectedGraphs[0].Edges.Count()); }
/*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); }