protected virtual void GenerateSpanningTree(CancellationToken cancellationToken) { SpanningTree = new BidirectionalGraph <TVertex, Edge <TVertex> >(false); SpanningTree.AddVertexRange(VisitedGraph.Vertices.OrderBy(v => VisitedGraph.InDegree(v))); EdgeAction <TVertex, TEdge> action = e => { cancellationToken.ThrowIfCancellationRequested(); SpanningTree.AddEdge(new Edge <TVertex>(e.Source, e.Target)); }; switch (Parameters.SpanningTreeGeneration) { case SpanningTreeGeneration.BFS: var bfsAlgo = new BreadthFirstSearchAlgorithm <TVertex, TEdge>(VisitedGraph); bfsAlgo.TreeEdge += action; bfsAlgo.Compute(); break; case SpanningTreeGeneration.DFS: var dfsAlgo = new DepthFirstSearchAlgorithm <TVertex, TEdge>(VisitedGraph); dfsAlgo.TreeEdge += action; dfsAlgo.ForwardOrCrossEdge += action; dfsAlgo.Compute(); break; } }
private void GenerateSpanningTree() { _spanningTree = new BidirectionalGraph <TVertex, Edge <TVertex> >(false); _spanningTree.AddVertexRange(VisitedGraph.Vertices); IQueue <TVertex> vb = new QuikGraph.Collections.Queue <TVertex>(); vb.Enqueue(VisitedGraph.Vertices.OrderBy(v => VisitedGraph.InDegree(v)).First()); switch (Parameters.SpanningTreeGeneration) { case SpanningTreeGeneration.BFS: var bfs = new BreadthFirstSearchAlgorithm <TVertex, TEdge>(VisitedGraph, vb, new Dictionary <TVertex, GraphColor>()); bfs.TreeEdge += e => { ThrowIfCancellationRequested(); _spanningTree.AddEdge(new Edge <TVertex>(e.Source, e.Target)); }; bfs.Compute(); break; case SpanningTreeGeneration.DFS: var dfs = new DepthFirstSearchAlgorithm <TVertex, TEdge>(VisitedGraph); dfs.TreeEdge += e => { ThrowIfCancellationRequested(); _spanningTree.AddEdge(new Edge <TVertex>(e.Source, e.Target)); }; dfs.Compute(); break; } }
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); }