예제 #1
0
        /// <summary>
        /// The function FeasibleTree constructs an initial feasible spanning tree.
        /// </summary>
        void FeasibleTree()
        {
            InitLayer();

            while (TightTree() < this.graph.NodeCount)
            {
                PolyIntEdge e = GetNonTreeEdgeIncidentToTheTreeWithMinimalAmountOfSlack();
                if (e == null)
                {
                    break; //all edges are tree edges
                }
                int slack = Slack(e);
                if (slack == 0)
                {
                    throw new InvalidOperationException();//"the tree should be tight");
                }
                if (inTree[e.Source])
                {
                    slack = -slack;
                }

                //shift the tree rigidly up or down and make e tight ; since the slack is the minimum of slacks
                //the layering will still remain feasible
                foreach (int i in treeVertices)
                {
                    layers[i] += slack;
                }
            }

            InitCutValues();
        }
        void RouteEdgeWithLabel(PolyIntEdge intEdge, Label label)
        {
            //we allow here for the edge to cross its own label
            Node             sourceNode    = routing.IntGraph.Nodes[intEdge.Source];
            Node             targetNode    = routing.IntGraph.Nodes[intEdge.Target];
            var              sourcePort    = new FloatingPort(sourceNode.BoundaryCurve, sourceNode.Center);
            var              targetPort    = new FloatingPort(targetNode.BoundaryCurve, targetNode.Center);
            ICurve           labelObstacle = labelsToLabelObstacles[label];
            var              labelPort     = new FloatingPort(labelObstacle, label.Center);
            SmoothedPolyline poly0;

            interactiveEdgeRouter.RouteSplineFromPortToPortWhenTheWholeGraphIsReady(sourcePort, labelPort, true, out poly0);
            SmoothedPolyline poly1;

            interactiveEdgeRouter.RouteSplineFromPortToPortWhenTheWholeGraphIsReady(labelPort, targetPort, true, out poly1);
            Site site = poly1.HeadSite.Next;

            Site lastSite = poly0.LastSite;

            lastSite.Next = site;
            site.Previous = lastSite;
            var eg = intEdge.Edge.EdgeGeometry;

            eg.SetSmoothedPolylineAndCurve(poly0);
            Arrowheads.TrimSplineAndCalculateArrowheads(eg, intEdge.Edge.Source.BoundaryCurve,
                                                        intEdge.Edge.Target.BoundaryCurve, eg.Curve, false);
        }
예제 #3
0
 internal static int GetSource(ref int currentVV, PolyIntEdge e, int i)
 {
     if (i == 0)
     {
         return(e.Source);
     }
     return(currentVV++);
 }
예제 #4
0
 internal static int GetTarget(ref int currentVV, PolyIntEdge e, int i, int span)
 {
     if (i < span - 1)
     {
         return(currentVV);
     }
     return(e.Target);
 }
예제 #5
0
 ///// <summary>
 ///// mark the vertex as one representing a label
 ///// or a middle of a multi edge
 ///// </summary>
 ///// <param name="db"></param>
 ///// <param name="bucket"></param>
 ///// <param name="parent"></param>
 ///// <param name="i"></param>
 internal static void RegisterDontStepOnVertex(Database db, PolyIntEdge parent)
 {
     if (db.Multiedges[new IntPair(parent.Source, parent.Target)].Count > 1)
     {
         LayerEdge e = parent.LayerEdges[parent.LayerEdges.Count / 2];
         db.MultipleMiddles.Insert(e.Source);
     }
 }
예제 #6
0
        internal PolyIntEdge GluedIntEdge(PolyIntEdge intEdge)
        {
            int         sourceRepr = NodeToRepr(intEdge.Source);
            int         targetRepr = NodeToRepr(intEdge.Target);
            PolyIntEdge ie         = new PolyIntEdge(sourceRepr, targetRepr);

            ie.Separation = intEdge.Separation;
            ie.Weight     = 0;
            ie.Edge       = intEdge.Edge;
            return(ie);
        }
 void RouteEdge(PolyIntEdge edge)
 {
     if (edge.HasLabel)
     {
         RouteEdgeWithLabel(edge, edge.Edge.Label);
     }
     else
     {
         RouteEdgeWithNoLabel(edge);
     }
 }
 /// <summary>
 /// Creates a smoothed polyline
 /// </summary>
 internal SmoothedPolylineCalculator(PolyIntEdge edgePathPar, Anchor[] anchorsP, GeometryGraph origGraph, SugiyamaLayoutSettings settings, LayerArrays la, ProperLayeredGraph layerGraph, Database databaseP)
 {
     this.database      = databaseP;
     edgePath           = edgePathPar;
     anchors            = anchorsP;
     this.layerArrays   = la;
     this.originalGraph = origGraph;
     this.settings      = settings;
     this.layeredGraph  = layerGraph;
     eastHierarchy      = BuildEastHierarchy();
     westHierarchy      = BuildWestHierarchy();
 }
예제 #9
0
        int Slack(PolyIntEdge e)
        {
            int ret = layers[e.Source] - layers[e.Target] - e.Separation;

#if DEBUGNW
            if (ret < 0)
            {
                throw new Exception("separation is not satisfied");
            }
#endif
            return(ret);
        }
예제 #10
0
        void CreateSplineForNonSelfEdge(PolyIntEdge es, bool optimizeShortEdges) {
            this.ProgressStep();

            if (es.LayerEdges != null) {
                DrawSplineBySmothingThePolyline(es, optimizeShortEdges);
                if (!es.IsVirtualEdge)
                {
                    es.UpdateEdgeLabelPosition(Database.Anchors);
                    Arrowheads.TrimSplineAndCalculateArrowheads(es.Edge.EdgeGeometry, es.Edge.Source.BoundaryCurve,
                                                                     es.Edge.Target.BoundaryCurve, es.Curve, true);
                }
            }
        }
예제 #11
0
 void DrawSplineBySmothingThePolyline(PolyIntEdge edgePath, bool optimizeShortEdges) {
     var smoothedPolyline = new SmoothedPolylineCalculator(edgePath, Database.Anchors, OriginalGraph, settings,
                                                           LayerArrays,
                                                           ProperLayeredGraph, Database);
     ICurve spline = smoothedPolyline.GetSpline(optimizeShortEdges);
     if (edgePath.Reversed) {
         edgePath.Curve = spline.Reverse();
         edgePath.UnderlyingPolyline = smoothedPolyline.Reverse().GetPolyline;
     }
     else {
         edgePath.Curve = spline;
         edgePath.UnderlyingPolyline = smoothedPolyline.GetPolyline;
     }
 }
        void RouteEdgeWithNoLabel(PolyIntEdge intEdge)
        {
            Node             sourceNode = routing.IntGraph.Nodes[intEdge.Source];
            Node             targetNode = routing.IntGraph.Nodes[intEdge.Target];
            var              sourcePort = new FloatingPort(sourceNode.BoundaryCurve, sourceNode.Center);
            var              targetPort = new FloatingPort(targetNode.BoundaryCurve, targetNode.Center);
            var              eg         = intEdge.Edge.EdgeGeometry;
            SmoothedPolyline sp;

            eg.Curve = interactiveEdgeRouter.RouteSplineFromPortToPortWhenTheWholeGraphIsReady(sourcePort, targetPort, true, out sp);
            Arrowheads.TrimSplineAndCalculateArrowheads(eg, intEdge.Edge.Source.BoundaryCurve,
                                                        intEdge.Edge.Target.BoundaryCurve, eg.Curve, false);
            intEdge.Edge.EdgeGeometry = eg;
        }
예제 #13
0
        /// <summary>
        /// one of the returned edge vertices does not belong to the tree but another does
        /// </summary>
        /// <returns></returns>
        NetworkEdge GetNonTreeEdgeIncidentToTheTreeWithMinimalAmountOfSlack()
        {
            PolyIntEdge eret     = null;
            int         minSlack = NetworkEdge.Infinity;

            foreach (int v in this.treeVertices)
            {
                foreach (NetworkEdge e in this.graph.OutEdges(v))
                {
                    if (inTree[e.Source] && inTree[e.Target])
                    {
                        continue;
                    }
                    int slack = Slack(e);
                    if (slack < minSlack)
                    {
                        eret     = e;
                        minSlack = slack;
                        if (slack == 1)
                        {
                            return(e);
                        }
                    }
                }

                foreach (NetworkEdge e in this.graph.InEdges(v))
                {
                    if (inTree[e.Source] && inTree[e.Target])
                    {
                        continue;
                    }


                    int slack = Slack(e);
                    if (slack < minSlack)
                    {
                        eret     = e;
                        minSlack = slack;
                        if (slack == 1)
                        {
                            return(e);
                        }
                    }
                }
            }

            return(eret as NetworkEdge);
        }
예제 #14
0
        internal void RegisterOriginalEdgeInMultiedges(PolyIntEdge edge)
        {
            IntPair            ip = new IntPair(edge.Source, edge.Target);
            List <PolyIntEdge> o;

            if (multiedges.ContainsKey(ip) == false)
            {
                multiedges[ip] = o = new List <PolyIntEdge>();
            }
            else
            {
                o = multiedges[ip];
            }

            o.Add(edge);
        }
예제 #15
0
        /// <summary>
        /// virtual nodes inside of an edge should be of the form i,i+1, ....
        /// </summary>
        private void EditOldLayering()
        {
            int curVNode = this.intGraph.NodeCount;

            foreach (List <PolyIntEdge> list in database.RegularMultiedges)
            {
                int         span = 0;
                PolyIntEdge e    = list[0];
                span = e.LayerSpan * 2;
                if (span > 0)  //ignoring flat edges
                {
                    foreach (LayerEdge le in e.LayerEdges)
                    {
                        if (le.Target != e.Target)
                        {
                            curVNode++;
                            UpdateOldLayer(curVNode++, le.Target);
                        }
                    }
                    curVNode += (span - 1) * (list.Count - 1) + 1;
                }
            }
        }
예제 #16
0
        /// <summary>
        /// Original layers are represented by even layers in the new layering.
        /// Here we add new virtices in such layers and
        /// set new x-offsets of original and dummy vertices in these layers.
        /// </summary>
        void WidenOriginalLayers()
        {
            for (int i = 0; i < la.Layers.Length; i++)
            {
                int[] layer  = nla.Layers[i * 2];
                int   offset = 0;
                foreach (int v in la.Layers[i])
                {
                    PolyIntEdge e = virtNodesToIntEdges[v];
                    if (e != null)
                    {
                        int layerOffsetInTheEdge = NLayering[e.Source] - NLayering[v];
                        List <PolyIntEdge> list  = database.Multiedges[new IntPair(e.Source, e.Target)];

                        foreach (PolyIntEdge ie in list)
                        {
                            if (ie != e)
                            {
                                int u = ie.LayerEdges[layerOffsetInTheEdge].Source;
                                layer[offset] = u;
                                nla.X[u]      = offset++;
                            }
                            else
                            {
                                layer[offset] = v;
                                nla.X[v]      = offset++;
                            }
                        }
                    }
                    else
                    {
                        layer[offset] = v;
                        nla.X[v]      = offset++;
                    }
                }
            }
        }
예제 #17
0
        public int[] GetLayers()
        {
            //sort the vertices in topological order
            int[] topoOrder = PolyIntEdge.GetOrder(graph);
            int[] layering  = new int[graph.NodeCount];

            //going backward from leaves
            int k = graph.NodeCount;

            while (k-- > 0)
            {
                int v = topoOrder[k];
                foreach (PolyIntEdge e in graph.InEdges(v))
                {
                    int u = e.Source;
                    int l = layering[v] + e.Separation;
                    if (layering[u] < l)
                    {
                        layering[u] = l;
                    }
                }
            }
            return(layering);
        }
예제 #18
0
        void CreateLayerEdgesUnderIntEdge(PolyIntEdge ie)
        {
            int source = ie.Source;
            int target = ie.Target;

            int span = LayeredLayoutEngine.EdgeSpan(initialLayering, ie);

            ie.LayerEdges = new LayerEdge[span];
            Debug.Assert(span > 0);
            if (span == 1)
            {
                ie.LayerEdges[0] = new LayerEdge(ie.Source, ie.Target, ie.CrossingWeight);
            }
            else
            {
                ie.LayerEdges[0] = new LayerEdge(source, numberOfNodesOfProperGraph, ie.CrossingWeight);
                for (int i = 0; i < span - 2; i++)
                {
                    ie.LayerEdges[i + 1] = new LayerEdge(numberOfNodesOfProperGraph++, numberOfNodesOfProperGraph,
                                                         ie.CrossingWeight);
                }
                ie.LayerEdges[span - 1] = new LayerEdge(numberOfNodesOfProperGraph++, target, ie.CrossingWeight);
            }
        }
        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]];
                }
            }
        }
 private static LayerEdge LastEdge(PolyIntEdge e)
 {
     return(e.LayerEdges[e.LayerEdges.Count - 1]);
 }
 private static LayerEdge FirstEdge(PolyIntEdge e)
 {
     return(e.LayerEdges[0]);
 }
예제 #22
0
 internal NetworkEdge(PolyIntEdge e)
     : base(e.Source, e.Target)
 {
     Weight     = e.Weight;
     Separation = e.Separation;
 }
예제 #23
0
 private bool FanAtSourceOrTarget(PolyIntEdge intEdge) {
     return ProperLayeredGraph.OutDegreeIsMoreThanOne(intEdge.Source) || ProperLayeredGraph.InDegreeIsMoreThanOne(intEdge.Target);
 }
예제 #24
0
 internal static NodeKind GetNodeKind(int vertexOffset, PolyIntEdge edgePath) {
     return vertexOffset == 0
                ? NodeKind.Top
                : (vertexOffset < edgePath.Count ? NodeKind.Internal : NodeKind.Bottom);
 }
예제 #25
0
 private IntPair GluedIntPair(PolyIntEdge p)
 {
     return(new IntPair(NodeToRepr(p.Source), NodeToRepr(p.Target)));
 }
예제 #26
0
 private bool EdgeIsFlat(PolyIntEdge ie)
 {
     return(la.Y[ie.Source] == la.Y[ie.Target]);
 }