Exemplo n.º 1
0
        internal static RectangleNode <Polyline> ReplaceTightObstaclesWithConvexHulls(Set <Polyline> tightObsts, IEnumerable <Tuple <Polyline, Polyline> > overlappingPairSet)
        {
            var overlapping = new Set <Polyline>();

            foreach (var pair in overlappingPairSet)
            {
                overlapping.Insert(pair.Item1);
                overlapping.Insert(pair.Item2);
            }
            var intToPoly = overlapping.ToArray();
            var polyToInt = MapToInt(intToPoly);
            var graph     = new BasicGraph <IntPair>(
                overlappingPairSet.
                Select(pair => new IntPair(polyToInt[pair.Item1], polyToInt[pair.Item2])));
            var connectedComponents = ConnectedComponentCalculator <IntPair> .GetComponents(graph);

            foreach (var component in connectedComponents)
            {
                var polys      = component.Select(i => intToPoly[i]);
                var points     = polys.SelectMany(p => p);
                var convexHull = ConvexHull.CreateConvexHullAsClosedPolyline(points);
                foreach (var poly in polys)
                {
                    tightObsts.Remove(poly);
                }
                tightObsts.Insert(convexHull);
            }
            return(CalculateHierarchy(tightObsts));
        }
Exemplo n.º 2
0
        void UniteConnectedPreGraphs(ref List <PreGraph> preGraphs)
        {
            BasicGraph <IntPair> intersectionGraph = GetIntersectionGraphOfPreGraphs(preGraphs);

            if (intersectionGraph == null)
            {
                return;
            }
            var connectedComponents = ConnectedComponentCalculator <IntPair> .GetComponents(intersectionGraph);

            var newPreGraphList = new List <PreGraph>();

            foreach (var component in connectedComponents)
            {
                PreGraph preGraph = null;
                foreach (var i in component)
                {
                    if (preGraph == null)
                    {
                        preGraph = preGraphs[i];
                        newPreGraphList.Add(preGraph);
                    }
                    else
                    {
                        preGraph.AddGraph(preGraphs[i]);
                    }
                }
            }
            preGraphs = newPreGraphList;
            foreach (var pg in preGraphs)
            {
                AddIntersectingNodes(pg);
            }
        }
Exemplo n.º 3
0
        ///// <summary>
        ///// Computes distances between a selected set of nodes and all nodes.
        ///// Pivot nodes are selected with maxmin strategy (first at random, later
        ///// ones to maximize distances to all previously selected ones).
        ///// </summary>
        ///// <param name="graph">A graph.</param>
        ///// <param name="directed">Whether shortest paths are directed.</param>
        ///// <param name="numberOfPivots">Number of pivots.</param>
        ///// <returns>A square matrix with shortest path distances.</returns>
        //public static double[][] PivotUniformDistances(GeometryGraph graph, bool directed, int numberOfPivots) {
        //    double[][] d = new double[numberOfPivots][];

        //    Node[] nodes = new Node[graph.Nodes.Count];
        //    graph.Nodes.CopyTo(nodes, 0);
        //    double[] min = new double[graph.Nodes.Count];
        //    for (int i = 0; i < min.Length; i++) {
        //        min[i] = Double.PositiveInfinity;
        //    }
        //    System.Console.Write("pivoting ");
        //    Node pivot = nodes[0];
        //    for (int i = 0; i < numberOfPivots; i++) {
        //        System.Console.Write(".");
        //        d[i] = SingleSourceUniformDistances(graph, pivot, directed);
        //        int argmax = 0;
        //        for (int j = 0; j < d[i].Length; j++) {
        //            min[j] = Math.Min(min[j], d[i][j]);
        //            if (min[j] > min[argmax])
        //                argmax = j;
        //        }
        //        pivot = nodes[argmax];
        //    }
        //    System.Console.WriteLine();
        //    return d;
        //}



        ///// <summary>
        ///// Determines whether the graph is (weakly) connected, that is,
        ///// if there is a path connecting every two nodes.
        ///// </summary>
        ///// <param name="graph">A graph.</param>
        ///// <returns>true iff the graph is connected.</returns>
        //public static bool IsConnected(GeometryGraph graph) {
        //    IEnumerator<Node> enumerator = graph.Nodes.GetEnumerator();
        //    enumerator.MoveNext();
        //    Node node=enumerator.Current;
        //    double[] distances=SingleSourceUniformDistances(graph, node, false);
        //    for (int i = 0; i < distances.Length; i++) {
        //        if (distances[i] == Double.PositiveInfinity) return false;
        //    }
        //    return true;
        //}

        /// <summary>
        /// Gives graphs representing the connected components of the graph
        /// </summary>
        /// <param name="graph">A graph.</param>
        /// <param name="nodeToNodeIndex">the dictionary: node -> node index in the NodeMap</param>
        /// <returns>An array of connected components.</returns>

        internal static GeometryGraph[] ComponentGraphs(GeometryGraph graph, Dictionary <Node, int> nodeToNodeIndex)
        {
            Node[] nodes = new Node[graph.Nodes.Count];
            graph.Nodes.CopyTo(nodes, 0);

            BasicGraph <IntPair> basicGraph = new BasicGraph <IntPair>(
                from edge in graph.Edges
                where !(edge.Source is Cluster || edge.Target is Cluster)
                select new IntPair(nodeToNodeIndex[edge.Source], nodeToNodeIndex[edge.Target]), graph.Nodes.Count);
            List <IEnumerable <int> > comps = new List <IEnumerable <int> >(ConnectedComponentCalculator <IntPair> .GetComponents(basicGraph));

            if (comps.Count == 1)
            {
                return new GeometryGraph[] { graph }
            }
            ;
            GeometryGraph[] ret = new GeometryGraph[comps.Count];
            int             i   = 0;

            foreach (var comp in comps)
            {
                ret[i++] = GeomGraphFromBasicGraph(comp, nodes);
            }

            return(ret);
        }
        /// <summary>
        /// These blocks are connected components in the vertical constraints. They don't necesserely span consequent layers.
        /// </summary>
        /// <returns></returns>
        Dictionary <int, int> CreateVerticalComponents()
        {
            var vertGraph          = new BasicGraph <IntEdge>(from pair in horizontalConstraints.VerticalInts select new IntEdge(pair.Item1, pair.Item2));
            var verticalComponents = ConnectedComponentCalculator <IntEdge> .GetComponents(vertGraph);

            var nodesToComponentRoots = new Dictionary <int, int>();

            foreach (var component in verticalComponents)
            {
                var ca = component.ToArray();
                if (ca.Length == 1)
                {
                    continue;
                }
                int componentRoot = -1;
                foreach (var j in component)
                {
                    if (componentRoot == -1)
                    {
                        componentRoot = j;
                    }
                    nodesToComponentRoots[j] = componentRoot;
                }
            }
            return(nodesToComponentRoots);
        }
Exemplo n.º 5
0
        private bool CreateConvexHulls()
        {
            var found = false;
            var graph = new BasicGraph <IntPair>(this.overlapPairs);
            var connectedComponents = ConnectedComponentCalculator <IntPair> .GetComponents(graph);

            foreach (var component in connectedComponents)
            {
                // GetComponents returns at least one self-entry for each index - including the < FirstNonSentinelOrdinal ones.
                if (component.Count() == 1)
                {
                    continue;
                }

                found = true;
                var obstacles = component.Select(this.OrdinalToObstacle);
                var points    = obstacles.SelectMany(obs => obs.VisibilityPolyline);
                var och       = new OverlapConvexHull(ConvexHull.CreateConvexHullAsClosedPolyline(points), obstacles);
                foreach (var obstacle in obstacles)
                {
                    obstacle.SetConvexHull(och);
                }
            }
            return(found);
        }
        private void CreateDictionaryOfSameLayerRepresentatives()
        {
            BasicGraph <IntPair> graphOfSameLayers = CreateGraphOfSameLayers();

            foreach (var comp in ConnectedComponentCalculator <IntPair> .GetComponents(graphOfSameLayers))
            {
                GlueSameLayerNodesOfALayer(comp);
            }
        }
Exemplo n.º 7
0
        void CreateConnectedGraphs()
        {
            Dictionary <Node, int> nodeToIndex;
            var listOfNodes = CreateNodeListForBasicGraph(out nodeToIndex);
            var basicGraph  = new BasicGraph <SimpleIntEdge>(GetSimpleIntEdges(nodeToIndex), listOfNodes.Count);
            var comps       = ConnectedComponentCalculator <SimpleIntEdge> .GetComponents(basicGraph);

            foreach (var comp in comps)
            {
                lgData.AddConnectedGeomGraph(GetConnectedSubgraph(comp, listOfNodes));
            }
        }
        /// <summary>
        /// For a set of nodes and edges that have not already been added to a graph will return an enumerable of new
        /// graphs each of which contains a connected component.
        /// </summary>
        /// <remarks>
        /// Debug.Asserts that Parent of nodes and edges has not yet been assigned to ensure that this is not being
        /// applied to nodes and edges that have already been added to a graph.  Applying this to such edges would
        /// result in the Node InEdges and OutEdges lists containing duplicates.
        /// </remarks>
        /// <returns></returns>
        public static IEnumerable <GeometryGraph> CreateComponents(IList <Node> nodes, IEnumerable <Edge> edges, double nodeSeparation)
        {
            ValidateArg.IsNotNull(nodes, "nodes");
            ValidateArg.IsNotNull(edges, "edges");
            var nodeIndex = new Dictionary <Node, int>();
            int nodeCount = 0;

            foreach (var v in nodes)
            {
                // Debug.Assert(v.Parent == null, "Node is already in a graph");
                nodeIndex[v] = nodeCount++;
            }
            var intEdges = new List <SimpleIntEdge>();

            foreach (var e in edges)
            {
                // Debug.Assert(e.Parent == null, "Edge is already in a graph");
                intEdges.Add(new SimpleIntEdge {
                    Source = nodeIndex[e.Source], Target = nodeIndex[e.Target]
                });
            }
            var components =
                ConnectedComponentCalculator <SimpleIntEdge> .GetComponents(new BasicGraphOnEdges <SimpleIntEdge>(intEdges,
                                                                                                                  nodeCount));

            var nodeToGraph = new Dictionary <Node, GeometryGraph>();
            var graphs      = new List <GeometryGraph>();

            foreach (var c in components)
            {
                var g = new GeometryGraph()
                {
                    Margins = nodeSeparation / 2
                };

                foreach (var i in c)
                {
                    var v = nodes[i];
                    g.Nodes.Add(v);
                    nodeToGraph[v] = g;
                }
                graphs.Add(g);
            }
            foreach (var e in edges)
            {
                var g = nodeToGraph[e.Source];
                Debug.Assert(nodeToGraph[e.Target] == g, "source and target of edge are not in the same graph");
                g.Edges.Add(e);
            }
            return(graphs);
        }
        private void CreateClumps()
        {
            var graph = new BasicGraphOnEdges <IntPair>(this.overlapPairs);
            var connectedComponents = ConnectedComponentCalculator <IntPair> .GetComponents(graph);

            foreach (var component in connectedComponents)
            {
                // GetComponents returns at least one self-entry for each index - including the < FirstNonSentinelOrdinal ones.
                if (component.Count() == 1)
                {
                    continue;
                }
                createClump(component);
            }
        }
Exemplo n.º 10
0
        private void CreateClumps()
        {
            var graph = new BasicGraph <IntPair>(this.overlapPairs);
            var connectedComponents = ConnectedComponentCalculator <IntPair> .GetComponents(graph);

            foreach (var component in connectedComponents)
            {
                // GetComponents returns at least one self-entry for each index - including the < FirstNonSentinelOrdinal ones.
                if (component.Count() == 1)
                {
                    continue;
                }
                var clump = new Clump(component.Select(this.OrdinalToObstacle));
                foreach (var obstacle in clump)
                {
                    obstacle.Clump = clump;
                }
            }
        }
        public void InitConnectedComponents(List <SymmetricSegment> edges)
        {
            var treeNodes = new TreeNode[pointToTreeNode.Count];

            foreach (var node in pointToTreeNode.Values)
            {
                treeNodes[node.id] = node;
            }

            var intEdges = new List <SimpleIntEdge>();

            foreach (var edge in edges)
            {
                int sourceId = pointToTreeNode[edge.A].id;
                int targetId = pointToTreeNode[edge.B].id;
                intEdges.Add(new SimpleIntEdge {
                    Source = sourceId, Target = targetId
                });
            }
            var components = ConnectedComponentCalculator <SimpleIntEdge> .GetComponents(new BasicGraph <SimpleIntEdge>(intEdges, pointToTreeNode.Count));

            foreach (var component in components)
            {
                List <TreeNode> nodeList = new List <TreeNode>();
                foreach (var nodeId in component)
                {
                    nodeList.Add(treeNodes[nodeId]);
                }

                _subtrees.Add(nodeList);
            }

            //ChooseRoots();
            ChooseRootsRandom();

            BuildForestFromCdtEdges(edges);

            foreach (var root in _roots)
            {
                OrientTreeEdges(root);
            }
        }
Exemplo n.º 12
0
        public int[] GetLayers()
        {
            List <IEnumerable <int> > comps = new List <IEnumerable <int> >(ConnectedComponentCalculator <IntEdge> .GetComponents(graph));

            if (comps.Count == 1)
            {
                NetworkSimplex ns = new NetworkSimplex(graph, this.Cancel);
                return(ns.GetLayers());
            }
            List <Dictionary <int, int> > mapToComponenents = GetMapsToComponent(comps);

            int[][] layerings = new int[comps.Count][];

            for (int i = 0; i < comps.Count; i++)
            {
                BasicGraph <Node, IntEdge> shrunkedComp = ShrunkComponent(mapToComponenents[i]);
                NetworkSimplex             ns           = new NetworkSimplex(shrunkedComp, Cancel);
                layerings[i] = ns.GetLayers();
            }

            return(UniteLayerings(layerings, mapToComponenents));
        }
Exemplo n.º 13
0
        /// <summary>
        /// Extension method to break a GeometryGraph into connected components taking into consideration clusters.
        /// Leaves the original graph intact, the resultant components contain copies of the original elements, with
        /// the original elements referenced in their UserData properties.
        /// </summary>
        /// <returns>
        /// the set of components, each as its own GeometryGraph.
        /// </returns>
        public static IEnumerable <GeometryGraph> GetClusteredConnectedComponents(this GeometryGraph graph)
        {
            var flatGraph      = FlatGraph(graph);
            var basicFlatGraph = new BasicGraph <AlgorithmDataEdgeWrap>(
                from e in flatGraph.Edges
                select(AlgorithmDataEdgeWrap) e.AlgorithmData,
                flatGraph.Nodes.Count);
            var nodes           = flatGraph.Nodes.ToList();
            var graphComponents = new List <GeometryGraph>();

            foreach (
                var componentNodes in ConnectedComponentCalculator <AlgorithmDataEdgeWrap> .GetComponents(basicFlatGraph))
            {
                var g           = new GeometryGraph();
                var topClusters = new List <Cluster>();
                var topNodes    = new List <Node>();
                foreach (int i in componentNodes)
                {
                    var  v        = nodes[i];
                    var  original = (Node)v.UserData;
                    bool topLevel = ((AlgorithmDataNodeWrap)original.AlgorithmData).TopLevel;
                    if (v.UserData is Cluster)
                    {
                        if (topLevel)
                        {
                            topClusters.Add((Cluster)original);
                        }
                    }
                    else
                    {
                        // clear edges, we fix them up below
                        v.ClearEdges();

                        g.Nodes.Add(v);
                        if (topLevel)
                        {
                            topNodes.Add(v);
                        }
                    }
                }

                // copy the cluster hierarchies from the original graph
                int index = g.Nodes.Count;
                if (topClusters.Count != 0)
                {
                    var root = new Cluster(topNodes);
                    foreach (var top in topClusters)
                    {
                        root.AddChild(CopyCluster(top, ref index));
                    }

                    g.RootCluster = root;
                }

                // add the real edges from the original graph to the component graph
                foreach (var v in g.GetFlattenedNodesAndClusters())
                {
                    var original = v.UserData as Node;
                    Debug.Assert(original != null);
                    foreach (var e in original.InEdges)
                    {
                        var source = GetCopy(e.Source);
                        var target = GetCopy(e.Target);
                        var copy   = new Edge(source, target)
                        {
                            Length       = e.Length,
                            UserData     = e,
                            EdgeGeometry = e.EdgeGeometry
                        };
                        e.AlgorithmData = copy;
                        g.Edges.Add(copy);
                    }
                }

                graphComponents.Add(g);
            }
            return(graphComponents);
        }
Exemplo n.º 14
0
        /// <summary>
        /// Create the graph data structures.
        /// </summary>
        /// <param name="geometryGraph"></param>
        /// <param name="settings">The settings for the algorithm.</param>
        /// <param name="initialConstraintLevel">initialize at this constraint level</param>
        /// <param name="clusterSettings">settings by cluster</param>
        internal FastIncrementalLayout(GeometryGraph geometryGraph, FastIncrementalLayoutSettings settings,
                                       int initialConstraintLevel,
                                       Func <Cluster, LayoutAlgorithmSettings> clusterSettings)
        {
            graph                = geometryGraph;
            this.settings        = settings;
            this.clusterSettings = clusterSettings;
            int i = 0;
            ICollection <Node> allNodes = graph.Nodes;

            nodes = new FiNode[allNodes.Count];
            foreach (Node v in allNodes)
            {
                v.AlgorithmData = nodes[i] = new FiNode(i, v);
                i++;
            }

            clusterEdges.Clear();
            edges.Clear();

            foreach (Edge e in graph.Edges)
            {
                if (e.Source is Cluster || e.Target is Cluster)
                {
                    clusterEdges.Add(e);
                }
                else
                {
                    edges.Add(new FiEdge(e));
                }
                foreach (var l in e.Labels)
                {
                    l.InnerPoints = l.OuterPoints = null;
                }
            }
            SetLockNodeWeights();
            components = new List <FiNode[]>();
            if (!settings.InterComponentForces)
            {
                basicGraph = new BasicGraph <FiEdge>(edges, nodes.Length);
                foreach (var componentNodes in ConnectedComponentCalculator <FiEdge> .GetComponents(basicGraph))
                {
                    var vs = new FiNode[componentNodes.Count()];
                    int vi = 0;
                    foreach (int v in componentNodes)
                    {
                        vs[vi++] = nodes[v];
                    }
                    components.Add(vs);
                }
            }
            else // just one big component (regardless of actual edges)
            {
                components.Add(nodes);
            }
            horizontalSolver = new AxisSolver(true, nodes, new[] { geometryGraph.RootCluster }, settings.AvoidOverlaps,
                                              settings.MinConstraintLevel, clusterSettings)
            {
                OverlapRemovalParameters =
                    new OverlapRemovalParameters {
                    AllowDeferToVertical = true,
                    // use "ProportionalOverlap" mode only when iterative apply forces layout is being used.
                    // it is not necessary otherwise.
                    ConsiderProportionalOverlap = settings.ApplyForces
                }
            };
            verticalSolver = new AxisSolver(false, nodes, new[] { geometryGraph.RootCluster }, settings.AvoidOverlaps,
                                            settings.MinConstraintLevel, clusterSettings);

            SetupConstraints();
            geometryGraph.RootCluster.ComputeWeight();

            foreach (
                Cluster c in geometryGraph.RootCluster.AllClustersDepthFirst().Where(c => c.RectangularBoundary == null)
                )
            {
                c.RectangularBoundary = new RectangularClusterBoundary();
            }

            CurrentConstraintLevel = initialConstraintLevel;
        }