public void FullComponentCount() { var alg = new QuickGraph.Algorithms.ConnectedComponents.ConnectedComponentsAlgorithm <MapNode, UndirectedEdge <MapNode> >(Maps.Full); alg.Compute(); Assert.AreEqual(1, alg.ComponentCount); }
public static void removeVertexByDegree(List <int> N, List <int> U, List <int> V, List <double> W = null, List <Point3d> P = null, int degree = 3) { //1.0 Create undirected graph UndirectedGraph <string, TaggedEdge <string, double> > graph = GetUndirectedFullGraph(N, U, V, P); //2.0 Collect vertices that have certain degree of valence List <string> HighlightedNodes = new List <string>(); foreach (var v in graph.Vertices) { //Rhino.RhinoApp.WriteLine(graph.AdjacentDegree(v).ToString()); if (graph.AdjacentDegree(v) == degree) { Rhino.RhinoApp.WriteLine(degree.ToString()); HighlightedNodes.Add(v); } } //3.0 Remove vertices for (int i = 0; i < HighlightedNodes.Count; i++) { graph.RemoveVertex(HighlightedNodes[i]); } //4.0 Identify disconnected components var dfs = new QuickGraph.Algorithms.ConnectedComponents.ConnectedComponentsAlgorithm <string, TaggedEdge <string, double> >(graph); dfs.Compute(); Rhino.RhinoApp.WriteLine("Components count " + dfs.ComponentCount.ToString()); // graph.ConnectedComponents() }
public override void Compute(CancellationToken cancellationToken) { Sizes = new Dictionary <TVertex, Size>(VertexSizes); if (Parameters.Direction == LayoutDirection.LeftToRight || Parameters.Direction == LayoutDirection.RightToLeft) { //change the sizes foreach (var sizePair in Sizes.ToArray()) { Sizes[sizePair.Key] = new Size(sizePair.Value.Height, sizePair.Value.Width); } } if (Parameters.Direction == LayoutDirection.RightToLeft || Parameters.Direction == LayoutDirection.BottomToTop) { _direction = -1; } else { _direction = 1; } GenerateSpanningTree(cancellationToken); //DoWidthAndHeightOptimization(); var graph = new UndirectedBidirectionalGraph <TVertex, TEdge>(VisitedGraph); var scca = new QuickGraph.Algorithms.ConnectedComponents.ConnectedComponentsAlgorithm <TVertex, TEdge>(graph); scca.Compute(); // Order connected components by their vertices count // Group vertices by connected component (they should be placed together) // Order vertices inside each conected component by in degree first, then out dregee // (roots should be placed in the first layer and leafs in the last layer) var components = from e in scca.Components group e.Key by e.Value into c orderby c.Count() descending select c; foreach (var c in components) { var firstOfComponent = true; var vertices = from v in c orderby VisitedGraph.InDegree(v), VisitedGraph.OutDegree(v) descending select v; foreach (var source in vertices) { CalculatePosition(source, null, 0, firstOfComponent); if (firstOfComponent) { firstOfComponent = false; } } } AssignPositions(cancellationToken); }
public static Tuple <int, HashSet <Edge <int> > > RunWithKernel(UndirectedGraph <int, Edge <int> > graph) { //DrawGraph.drawGraph(graph, new HashSet<Edge<int>>(), @"C:\Users\Frederik\Desktop\a.dot"); var componentAlgorithm = new QuickGraph.Algorithms.ConnectedComponents.ConnectedComponentsAlgorithm <int, Edge <int> >(graph); componentAlgorithm.Compute(); var nodeToComponent = componentAlgorithm.Components; var time = DateTime.Now; var retk = 0; var retEdges = new HashSet <Edge <int> >(); for (int i = 0; i < componentAlgorithm.ComponentCount; i++) { var g = new UndirectedGraph <int, Edge <int> >(false); foreach (var v in graph.Vertices) { if (nodeToComponent[v] == i) { g.AddVertex(v); } } foreach (var v in g.Vertices) { foreach (var e in graph.AdjacentEdges(v)) { g.AddEdge(e); } } var kernel = Kernel.Init(CloneGraph(g)); //remember to clone graph, as the phases will "butcher" the graph. var tup = FindKKernel(g, time, kernel); var k = tup.Item1; var edges = tup.Item2; retk += k; foreach (var e in edges) { retEdges.Add(e); } } var clone2 = CloneGraph(graph); clone2.AddEdgeRange(retEdges); //DrawGraph.drawGraph(clone2, retEdges, @"C:\Users\Frederik\Desktop\b.dot"); return(new Tuple <int, HashSet <Edge <int> > >(retk, retEdges)); }
private static List <List <int> > FindMoplexes( UndirectedGraph <int, Edge <int> > graph, Dictionary <int, int> revOrdering, Dictionary <int, int> ordering, Dictionary <int, List <int> > labels, List <Edge <int> > newlyAddedEdges, List <List <int> > prevMoplexes) { var moplexes = new List <List <int> >(); var hasBeenChecked = new List <int>(); if (newlyAddedEdges != null) //newly added edge means that the moplexes effected must be recalculated. { if (prevMoplexes != null) { foreach (var e in newlyAddedEdges) { var validMoplexes = prevMoplexes.Where(moplex => //this should not work!?!?! We add moplexes if they are not effected by the first edge e.Source != moplex.First() && e.Target != moplex.First() && graph.AdjacentEdges(moplex.First()) .Select(edge => edge.GetOtherVertex(moplex.First())) .All(v => v != e.Source && v != e.Target) ).ToList(); moplexes.AddRange(validMoplexes); hasBeenChecked.AddRange(validMoplexes.SelectMany(i => i).Distinct()); } } } else if (prevMoplexes != null) // no newly added edge, so previously calculated moplex must still be relevant. { moplexes.AddRange(prevMoplexes); hasBeenChecked.AddRange(prevMoplexes.SelectMany(m => m).ToList()); } // Start finding new moplexes foreach (var v in labels.Keys) { if (hasBeenChecked.Contains(v)) // no vertex can be part of multiple moplexes { continue; } //equal neighbourhood check var potMoplex = new List <int>(); foreach (var i in labels.Keys) { if (labels[i] != null && labels[i].SequenceEqual(labels[v])) { potMoplex.Add(i); } } //find neighbourhood excl. the potential moplex, i.e. the seperator var seperator = labels[v].Select(l => revOrdering[l]).Except(potMoplex).ToList(); // Check that the seperator is minimal - i.e. check all vertices in the seperator is connected to all components // First: Remove seperator and moplex from graph (temporarily) var tempRemove = new List <Edge <int> >(); foreach (int mv in potMoplex) { tempRemove.AddRange(graph.AdjacentEdges(mv)); graph.RemoveVertex(mv); } foreach (var sv in seperator) { tempRemove.AddRange(graph.AdjacentEdges(sv)); graph.RemoveVertex(sv); } // Find connected components in the new graph var a = new QuickGraph.Algorithms.ConnectedComponents.ConnectedComponentsAlgorithm <int, Edge <int> >(graph); a.Compute(); var nodeToComponentDic = a.Components; // Add the seperator and potential moplex again graph.AddVertexRange(seperator); graph.AddVertexRange(potMoplex); graph.AddEdgeRange(tempRemove); var isMoplex = false; foreach (var sepNode in seperator) // Find the components connected to each of the seperator vertices { HashSet <int> connectedComponents = new HashSet <int>(); foreach (var e in graph.AdjacentEdges(sepNode)) { var neighbour = e.GetOtherVertex(sepNode); if (potMoplex.Contains(neighbour)) { continue; //not a component, since it was removed at the time } if (nodeToComponentDic.ContainsKey(neighbour)) //else neighbour is also seperator TODO: error here, Not anymore I think { int c; nodeToComponentDic.TryGetValue(neighbour, out c); connectedComponents.Add(c); } } if (connectedComponents.Count < a.ComponentCount || a.ComponentCount == 0) { isMoplex = false; break; } isMoplex = true; } if (isMoplex) { moplexes.Add(potMoplex); } // To ensure no dublicates foreach (var n in potMoplex) { hasBeenChecked.Add(n); } } return(moplexes); }