コード例 #1
0
        internal static RectangleNode <Polyline, Point> 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 BasicGraphOnEdges <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));
        }
コード例 #2
0
        void UniteConnectedPreGraphs(ref List <PreGraph> preGraphs)
        {
            BasicGraphOnEdges <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);
            }
        }
コード例 #3
0
        /// <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 BasicGraphOnEdges <PolyIntEdge>(from pair in horizontalConstraints.VerticalInts select new PolyIntEdge(pair.Item1, pair.Item2));
            var verticalComponents = ConnectedComponentCalculator <PolyIntEdge> .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);
        }
コード例 #4
0
        private void CreateDictionaryOfSameLayerRepresentatives()
        {
            BasicGraphOnEdges <IntPair> graphOfSameLayers = CreateGraphOfSameLayers();

            foreach (var comp in ConnectedComponentCalculator <IntPair> .GetComponents(graphOfSameLayers))
            {
                GlueSameLayerNodesOfALayer(comp);
            }
        }
コード例 #5
0
        static BasicGraphOnEdges <PolyIntEdge> CreateGraphWithIEEdges(BasicGraphOnEdges <PolyIntEdge> bg)
        {
            List <PolyIntEdge> ieEdges = new List <PolyIntEdge>();

            foreach (PolyIntEdge e in bg.Edges)
            {
                ieEdges.Add(new NetworkEdge(e));
            }

            return(new BasicGraphOnEdges <PolyIntEdge>(ieEdges, bg.NodeCount));
        }
コード例 #6
0
        int weightMultiplierOfTwoVirtual       = 8;                  //weight multiplier for edges with two virtual nodes

        internal XLayoutGraph(BasicGraphOnEdges <PolyIntEdge> graph, //DAG of the original graph with no multiple edges
                              ProperLayeredGraph layeredGraph,
                              LayerArrays layerArrays,
                              List <PolyIntEdge> edges,
                              int nov)
        {
            this.SetEdges(edges, nov);
            this.virtualVerticesStart = graph.NodeCount;
            this.virtualVerticesEnd   = layeredGraph.NodeCount - 1;
            this.layeredGraph         = layeredGraph;
            this.layerArrays          = layerArrays;
        }
コード例 #7
0
        void CreateGraphAndRemoveCycles()
        {
            //edges in the graph go from a smaller value to a bigger value
            graph = new BasicGraphOnEdges <IntPair>(constraints, varList.Count + boundsToInt.Count);
            //removing cycles
            var feedbackSet = CycleRemoval <IntPair> .GetFeedbackSet(graph);

            if (feedbackSet != null)
            {
                foreach (var edge in feedbackSet)
                {
                    graph.RemoveEdge(edge as IntPair);
                }
            }
        }
コード例 #8
0
        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);
            }
        }
コード例 #9
0
        /// <summary>
        /// Computes the minimum spanning tree on a DT with given weights.
        /// </summary>
        /// <param name="cdt"></param>
        /// <param name="weights"></param>
        /// <returns></returns>
        static internal List <CdtEdge> GetMstOnCdt(Cdt cdt, Func <CdtEdge, double> weights)
        {
            var siteArray = cdt.PointsToSites.Values.ToArray();
            var siteIndex = new Dictionary <CdtSite, int>();

            for (int i = 0; i < siteArray.Length; i++)
            {
                siteIndex[siteArray[i]] = i;
            }

            Dictionary <IntPair, CdtEdge> intPairsToCdtEdges = GetEdges(siteArray, siteIndex);

            var graph = new BasicGraphOnEdges <IEdge>(intPairsToCdtEdges.Keys, siteArray.Length);

            var mstOnBasicGraph = new MinimumSpanningTreeByPrim(graph, intPair => weights(intPairsToCdtEdges[(IntPair)intPair]), 0);

            return(new List <CdtEdge>(mstOnBasicGraph.GetTreeEdges().Select(e => intPairsToCdtEdges[(IntPair)e])));
        }
コード例 #10
0
        /// <summary>
        /// Computes the minimum spanning tree on a set of edges
        /// </summary>
        /// <param name="proximityEdges">list of tuples, each representing an edge with: nodeId1, nodeId2, t(overlapFactor), ideal distance, edge weight.</param>
        /// <param name="sizeId"></param>
        /// <returns></returns>
        static internal List <Tuple <int, int, double, double, double> > GetMstOnTuple(List <Tuple <int, int, double, double, double> > proximityEdges, int sizeId)
        {
            if (proximityEdges.Count == 0)
            {
                return(null);
            }
            var intPairs  = proximityEdges.Select(t => new IntPair(t.Item1, t.Item2)).ToArray();
            var weighting = new Dictionary <IntPair, Tuple <int, int, double, double, double> >(intPairs.Count());

            for (int i = 0; i < proximityEdges.Count; i++)
            {
                weighting[intPairs[i]] = proximityEdges[i];
            }
            var graph = new BasicGraphOnEdges <IEdge>(intPairs, sizeId);

            var mstOnBasicGraph = new MinimumSpanningTreeByPrim(graph, intPair => weighting[(IntPair)intPair].Item5, intPairs[0].First);

            List <Tuple <int, int, double, double, double> > treeEdges = mstOnBasicGraph.GetTreeEdges().Select(e => weighting[(IntPair)e]).ToList();

            return(treeEdges);
        }
コード例 #11
0
        public void SmallGraph()
        {
            // (ab)(bc)(cd)(dh)(af)(fg)(ae)(eg)(gh)
            int a = 0;
            int b = 1;
            int c = 2;
            int d = 3;
            int e = 4;
            int f = 5;
            int g = 6;
            int h = 7;
            Func <int, int, PolyIntEdge> edge = (int x, int y) => new PolyIntEdge(x, y, null)
            {
                Separation = 1
            };

            var edges = new PolyIntEdge[] { edge(a, b), edge(b, c), edge(c, d), edge(d, h), edge(a, f), edge(f, g), edge(a, e), edge(e, g), edge(g, h) };
            var graph = new BasicGraphOnEdges <PolyIntEdge>(edges);
            var ns    = new NetworkSimplex(graph, new CancelToken());

            ns.Run();
            Assert.AreEqual(ns.Weight, 10);
        }
        void CreateMappingOfNeibBlocks()
        {
            BasicGraphOnEdges <IntPair> graph = BasicGraphFromLeftRightIntNeibs();

            for (int root = 0; root < graph.NodeCount; root++)
            {
                if (graph.InEdges(root).Count == 0 && !nodeToBlockRoot.ContainsKey(root))
                {
                    var block   = new List <int>();
                    int current = root;
                    for (IList <IntPair> outEdges = graph.OutEdges(current); outEdges.Count > 0;
                         outEdges = graph.OutEdges(current))
                    {
                        current = outEdges[0].Second;
                        block.Add(current);
                        nodeToBlockRoot[current] = root;
                    }
                    if (block.Count > 0)
                    {
                        BlockRootToBlock[root] = block;
                    }
                }
            }
        }
コード例 #13
0
        private bool CreateConvexHulls()
        {
            var found = false;
            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;
                }
                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);
        }
コード例 #14
0
 internal NetworkSimplex(BasicGraphOnEdges <PolyIntEdge> graph, CancelToken cancelToken)
 {
     this.graph         = CreateGraphWithIEEdges(graph);
     inTree             = new bool[graph.NodeCount];
     NetworkCancelToken = cancelToken;
 }
コード例 #15
0
 private IEnumerable <IEdge> GetFeedbackSet()
 {
     this.gluedIntGraph = CreateGluedGraph();
     return(UnglueIntPairs(CycleRemoval <IntPair> .GetFeedbackSetWithConstraints(gluedIntGraph, this.GluedUpDownIntConstraints)));//avoiding lazy evaluation
 }
コード例 #16
0
        void AssignCoordinatesByLongestPath()
        {
            this.x = this.xCoords[this.EnumRightUp] = new double[this.nOfVertices];

            /*
             * We create a graph of blocks or rather of block roots. There is an edge
             * from u-block to v-block  if some of elements of u-block is to the left of v
             * on the same layer. Then we topologically sort the graph and assign coordinates
             * taking into account separation between the blocks.
             */
            //create the graph first
            List <PolyIntEdge> edges = new List <PolyIntEdge>();

            for (int v = 0; v < nOfVertices; v++)
            {
                if (v == root[v]) //v is a root
                {
                    int w = v;    //w will be running over the block
                    do
                    {
                        int rightNeighbor;
                        if (TryToGetRightNeighbor(w, out rightNeighbor))
                        {
                            edges.Add(new PolyIntEdge(v, root[rightNeighbor]));
                        }
                        w = align[w];
                    }while (w != v);
                }
            }

            BasicGraphOnEdges <PolyIntEdge> blockGraph = new BasicGraphOnEdges <PolyIntEdge>(edges, nOfVertices);

            //sort the graph in the topological order
            int[] topoSort = PolyIntEdge.GetOrder(blockGraph);
            //start placing the blocks according to the order

            foreach (int v in topoSort)
            {
                if (v == root[v])//not every element of topoSort is a root!
                {
                    double vx          = 0;
                    bool   vIsLeftMost = true;
                    int    w           = v;//w is running over the block
                    do
                    {
                        int wLeftNeighbor;
                        if (TryToGetLeftNeighbor(w, out wLeftNeighbor))
                        {
                            if (vIsLeftMost)
                            {
                                vx          = x[root[wLeftNeighbor]] + DeltaBetweenVertices(wLeftNeighbor, w);
                                vIsLeftMost = false;
                            }
                            else
                            {
                                vx = RightMost(vx, x[root[wLeftNeighbor]] + DeltaBetweenVertices(wLeftNeighbor, w));
                            }
                        }
                        w = align[w];
                    }while (w != v);

                    x[v] = vx;
                }
            }

            //push the roots of the graph maximally to the right
            foreach (int v in topoSort)
            {
                if (v == root[v])
                {
                    if (blockGraph.InEdges(v).Count == 0)
                    {
                        int    w         = v;//w runs over the block
                        double xLeftMost = RightMost(-infinity, infinity);
                        double xl        = xLeftMost;
                        do
                        {
                            int wRightNeigbor;
                            if (TryToGetRightNeighbor(w, out wRightNeigbor))
                            {
                                xLeftMost = LeftMost(xLeftMost,
                                                     x[root[wRightNeigbor]] - DeltaBetweenVertices(w, wRightNeigbor));
                            }

                            w = align[w];
                        } while (w != v);

                        //leave the value zero if there are no right neighbours
                        if (xl != xLeftMost)
                        {
                            x[v] = xLeftMost;
                        }
                    }
                }
            }

            for (int v = 0; v < this.nOfVertices; v++)
            {
                if (v != root[v])
                {
                    x[v] = x[root[v]];
                }
            }
        }
コード例 #17
0
 internal NetworkSimplexForGeneralGraph(BasicGraph <Node, PolyIntEdge> graph, CancelToken cancelObject)
 {
     this.graph  = graph;
     this.Cancel = cancelObject;
 }
コード例 #18
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 BasicGraphOnEdges <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);
        }
コード例 #19
0
 internal Succ(BasicGraphOnEdges <PolyIntEdge> g, int v)
 {
     this.graph = g;
     this.vert  = v;
 }
コード例 #20
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 BasicGraphOnEdges <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;
        }
コード例 #21
0
 internal LongestPathLayering(BasicGraphOnEdges <PolyIntEdge> graph)
 {
     this.graph = graph;
 }