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;
            }
        }
예제 #2
0
        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);
        }