예제 #1
0
        void RegisterAboveBelowOnConstrainedUpperLower(int upper, int lower)
        {
            LayerInfo topLayerInfo    = GetOrCreateLayerInfo(LayerArrays.Y[upper]);
            LayerInfo bottomLayerInfo = GetOrCreateLayerInfo(LayerArrays.Y[lower]);

            topLayerInfo.constrainedFromBelow[upper]    = lower;
            bottomLayerInfo.constrainedFromAbove[lower] = upper;
        }
예제 #2
0
 static bool NodeIsConstrainedAbove(int v, LayerInfo layerInfo)
 {
     if (layerInfo == null)
     {
         return(false);
     }
     return(layerInfo.constrainedFromAbove.ContainsKey(v));
 }
예제 #3
0
 void FillLeftRightPairs()
 {
     foreach (var p in horizontalConstraints.LeftRighInts)
     {
         LayerInfo layerInfo = GetOrCreateLayerInfo(initialLayering[p.Item1]);
         layerInfo.leftRight.Insert(p);
     }
 }
        double FixedNodePosition(int v, SweepMode sweepMode)
        {
            Debug.Assert(sweepMode != SweepMode.Starting);
            LayerInfo layerInfo = layerInfos[LayerArrays.Y[v]];

            return(sweepMode == SweepMode.ComingFromAbove
                       ? XPosition(layerInfo.constrainedFromAbove[v])
                       : XPosition(layerInfo.constrainedFromBelow[v]));
        }
 static bool NodeIsConstrained(int v, SweepMode sweepMode, LayerInfo layerInfo)
 {
     if (sweepMode == SweepMode.Starting)
     {
         return(false);
     }
     return(sweepMode == SweepMode.ComingFromAbove && NodeIsConstrainedAbove(v, layerInfo) ||
            sweepMode == SweepMode.ComingFromBelow && NodeIsConstrainedBelow(v, layerInfo));
 }
 internal AdjacentSwapsWithConstraints(LayerArrays layerArray,
                                       bool hasCrossWeights,
                                       ProperLayeredGraph properLayeredGraph,
                                       LayerInfo[] layerInfos) {
     X = layerArray.X;
     layering = layerArray.Y;
     layers = layerArray.Layers;
     this.properLayeredGraph = properLayeredGraph;
     this.hasCrossWeights = hasCrossWeights;
     this.layerInfos = layerInfos;
 }
 void FillBlockRootToBlock()
 {
     foreach (var p in horizontalConstraints.BlockRootToBlock)
     {
         LayerInfo layerInfo = GetOrCreateLayerInfo(initialLayering[p.Key]);
         layerInfo.neigBlocks[p.Key] = p.Value;
         foreach (int i in p.Value)
         {
             layerInfo.nodeToBlockRoot[i] = p.Key;
         }
     }
 }
 static bool TryGetBlockRoot(int v, out int blockRoot, LayerInfo layerInfo)
 {
     if (layerInfo.nodeToBlockRoot.TryGetValue(v, out blockRoot))
     {
         return(true);
     }
     if (layerInfo.neigBlocks.ContainsKey(v))
     {
         blockRoot = v;
         return(true);
     }
     return(false);
 }
        /// <summary>
        ///
        /// </summary>
        /// <param name="blockRoot"></param>
        /// <param name="layerInfo"></param>
        /// <param name="sweepMode"></param>
        /// <returns>-1 if no node is constrained</returns>
        static int GetFixedBlockNode(int blockRoot, LayerInfo layerInfo, SweepMode sweepMode)
        {
            if (sweepMode == SweepMode.Starting)
            {
                return(-1);
            }

            if (sweepMode == SweepMode.ComingFromBelow)
            {
                return(GetFixedBlockNodeFromBelow(blockRoot, layerInfo));
            }
            return(GetFixedBlockNodeFromAbove(blockRoot, layerInfo));
        }
 static IEnumerable <int> VertConstrainedNodesOfLayer(LayerInfo layerInfo)
 {
     if (layerInfo != null)
     {
         foreach (int v in layerInfo.constrainedFromAbove.Keys)
         {
             yield return(v);
         }
         foreach (int v in layerInfo.constrainedFromBelow.Keys)
         {
             yield return(v);
         }
     }
 }
        double GetGapFromNodeNodesConstrainedBelow(int leftNode, int rightNode, LayerInfo layerInfo,
                                                   int layerIndex)
        {
            double gap = SimpleGapBetweenTwoNodes(leftNode, rightNode);

            leftNode  = layerInfo.constrainedFromBelow[leftNode];
            rightNode = layerInfo.constrainedFromBelow[rightNode];
            layerIndex--;
            layerInfo = layerInfos[layerIndex];
            if (layerIndex > 0 && NodesAreConstrainedBelow(leftNode, rightNode, layerInfo))
            {
                return(Math.Max(gap, GetGapFromNodeNodesConstrainedBelow(leftNode, rightNode, layerInfo, layerIndex)));
            }
            return(Math.Max(gap, SimpleGapBetweenTwoNodes(leftNode, rightNode)));
        }
 static void AddGoalToKeepFlatEdgesShortOnBlockLevel(LayerInfo layerInfo, ISolverShell solver)
 {
     if (layerInfo != null)
     {
         foreach (var couple in layerInfo.flatEdges)
         {
             int sourceBlockRoot = NodeToBlockRootSoftOnLayerInfo(layerInfo, couple.Item1);
             int targetBlockRoot = NodeToBlockRootSoftOnLayerInfo(layerInfo, couple.Item2);
             if (sourceBlockRoot != targetBlockRoot)
             {
                 solver.AddGoalTwoVariablesAreClose(sourceBlockRoot, targetBlockRoot);
             }
         }
     }
 }
 static int GetFixedBlockNodeFromAbove(int blockRoot, LayerInfo layerInfo)
 {
     if (layerInfo.constrainedFromAbove.ContainsKey(blockRoot))
     {
         return(blockRoot);
     }
     foreach (int v in layerInfo.neigBlocks[blockRoot])
     {
         if (layerInfo.constrainedFromAbove.ContainsKey(v))
         {
             return(v);
         }
     }
     return(-1);
 }
        double GetGapFromNodeNodesConstrainedAbove(int leftNode, int rightNode, LayerInfo layerInfo,
                                                   int layerIndex)
        {
            double gap = SimpleGapBetweenTwoNodes(leftNode, rightNode);

            leftNode  = layerInfo.constrainedFromAbove[leftNode];
            rightNode = layerInfo.constrainedFromAbove[rightNode];
            layerIndex++;
            layerInfo = layerInfos[layerIndex];
            if (layerIndex < LayerArrays.Layers.Length - 1 && NodesAreConstrainedAbove(leftNode, rightNode, layerInfo))
            {
                return(Math.Max(gap, GetGapFromNodeNodesConstrainedAbove(leftNode, rightNode, layerInfo, layerIndex)));
            }
            return(Math.Max(gap, SimpleGapBetweenTwoNodes(leftNode, rightNode)));
        }
        //at the moment we only are looking for the order of nodes in the layer
        void FillSolverWithoutKnowingLayerOrder(IEnumerable <int> layer, LayerInfo layerInfo, ISolverShell solver,
                                                SweepMode sweepMode)
        {
            foreach (int v in layer)
            {
                if (layerInfo.neigBlocks.ContainsKey(v))
                {
                    //v is a block root
                    int blockNode = GetFixedBlockNode(v, layerInfo, sweepMode);
                    if (blockNode != -1)
                    {
                        solver.AddVariableWithIdealPosition(v, FixedNodePosition(blockNode, sweepMode),
                                                            ConstrainedVarWeight);
                    }
                    else
                    {
                        IEnumerable <int> t = from u in layerInfo.neigBlocks[v].Concat(new[] { v })
                                              where IsConnectedToPrevLayer(u, sweepMode)
                                              select u;
                        if (t.Any())
                        {
                            blockNode = t.First();
                            solver.AddVariableWithIdealPosition(v, GetBaricenterOnPrevLayer(blockNode, sweepMode));
                        }
                    }
                }
                else if (!BelongsToNeighbBlock(v, layerInfo))
                {
                    if (NodeIsConstrained(v, sweepMode, layerInfo))
                    {
                        solver.AddVariableWithIdealPosition(v, FixedNodePosition(v, sweepMode), ConstrainedVarWeight);
                    }
                    else if (IsConnectedToPrevLayer(v, sweepMode))
                    {
                        solver.AddVariableWithIdealPosition(v, GetBaricenterOnPrevLayer(v, sweepMode));
                    }
                }
            }

            AddGoalToKeepFlatEdgesShortOnBlockLevel(layerInfo, solver);

            foreach (var p in layerInfo.leftRight)
            {
                solver.AddLeftRightSeparationConstraint(p.Item1, p.Item2, GetGapBetweenBlockRoots(p.Item1, p.Item2));
            }
        }
 double GetGapFromNodeNodesConstrainedBelow(int leftNode, int rightNode, LayerInfo layerInfo,
                                                   int layerIndex) {
     double gap = SimpleGapBetweenTwoNodes(leftNode, rightNode);
     leftNode = layerInfo.constrainedFromBelow[leftNode];
     rightNode = layerInfo.constrainedFromBelow[rightNode];
     layerIndex--;
     layerInfo = layerInfos[layerIndex];
     if (layerIndex > 0 && NodesAreConstrainedBelow(leftNode, rightNode, layerInfo))
         return Math.Max(gap, GetGapFromNodeNodesConstrainedBelow(leftNode, rightNode, layerInfo, layerIndex));
     return Math.Max(gap, SimpleGapBetweenTwoNodes(leftNode, rightNode));
 }
 static void AddGoalToKeepFlatEdgesShortOnBlockLevel(LayerInfo layerInfo, ISolverShell solver) {
     if (layerInfo != null)
         foreach (var couple in layerInfo.flatEdges) {
             int sourceBlockRoot = NodeToBlockRootSoftOnLayerInfo(layerInfo, couple.Item1);
             int targetBlockRoot = NodeToBlockRootSoftOnLayerInfo(layerInfo, couple.Item2);
             if (sourceBlockRoot != targetBlockRoot)
                 solver.AddGoalTwoVariablesAreClose(sourceBlockRoot, targetBlockRoot);
         }
 }
 static bool TryGetBlockRoot(int v, out int blockRoot, LayerInfo layerInfo) {
     if (layerInfo.nodeToBlockRoot.TryGetValue(v, out blockRoot))
         return true;
     if (layerInfo.neigBlocks.ContainsKey(v)) {
         blockRoot = v;
         return true;
     }
     return false;
 }
        //at the moment we only are looking for the order of nodes in the layer
        void FillSolverWithoutKnowingLayerOrder(IEnumerable<int> layer, LayerInfo layerInfo, ISolverShell solver,
                                                       SweepMode sweepMode) {
            foreach (int v in layer)
                if (layerInfo.neigBlocks.ContainsKey(v)) {
                    //v is a block root
                    int blockNode = GetFixedBlockNode(v, layerInfo, sweepMode);
                    if (blockNode != -1)
                        solver.AddVariableWithIdealPosition(v, FixedNodePosition(blockNode, sweepMode),
                                                            ConstrainedVarWeight);
                    else {
                        IEnumerable<int> t = from u in layerInfo.neigBlocks[v].Concat(new[] { v })
                                             where IsConnectedToPrevLayer(u, sweepMode)
                                             select u;
                        if (t.Any()) {
                            blockNode = t.First();
                            solver.AddVariableWithIdealPosition(v, GetBaricenterOnPrevLayer(blockNode, sweepMode));
                        }
                    }
                } else if (!BelongsToNeighbBlock(v, layerInfo)) {
                    if (NodeIsConstrained(v, sweepMode, layerInfo))
                        solver.AddVariableWithIdealPosition(v, FixedNodePosition(v, sweepMode), ConstrainedVarWeight);
                    else if (IsConnectedToPrevLayer(v, sweepMode))
                        solver.AddVariableWithIdealPosition(v, GetBaricenterOnPrevLayer(v, sweepMode));
                }

            AddGoalToKeepFlatEdgesShortOnBlockLevel(layerInfo, solver);

            foreach (var p in layerInfo.leftRight)
                solver.AddLeftRightSeparationConstraint(p.Item1, p.Item2, GetGapBetweenBlockRoots(p.Item1, p.Item2));
        }
        /// <summary>
        /// when we call this function we know that a LayerInfo is needed
        /// </summary>
        /// <param name="layerNumber"></param>
        /// <returns></returns>
        LayerInfo GetOrCreateLayerInfo(int layerNumber)
        {
            LayerInfo layerInfo = layerInfos[layerNumber] ?? (layerInfos[layerNumber] = new LayerInfo());

            return(layerInfo);
        }
 static int NodeToBlockRootSoftOnLayerInfo(LayerInfo layerInfo, int node) {
     int root;
     return layerInfo.nodeToBlockRoot.TryGetValue(node, out root) ? root : node;
 }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="blockRoot"></param>
        /// <param name="layerInfo"></param>
        /// <param name="sweepMode"></param>
        /// <returns>-1 if no node is constrained</returns>
        static int GetFixedBlockNode(int blockRoot, LayerInfo layerInfo, SweepMode sweepMode) {
            if (sweepMode == SweepMode.Starting)
                return -1;

            if (sweepMode == SweepMode.ComingFromBelow)
                return GetFixedBlockNodeFromBelow(blockRoot, layerInfo);
            return GetFixedBlockNodeFromAbove(blockRoot, layerInfo);
        }
 static int GetFixedBlockNodeFromAbove(int blockRoot, LayerInfo layerInfo) {
     if (layerInfo.constrainedFromAbove.ContainsKey(blockRoot))
         return blockRoot;
     foreach (int v in layerInfo.neigBlocks[blockRoot])
         if (layerInfo.constrainedFromAbove.ContainsKey(v))
             return v;
     return -1;
 }
 /// <summary>
 /// when we call this function we know that a LayerInfo is needed
 /// </summary>
 /// <param name="layerNumber"></param>
 /// <returns></returns>
 LayerInfo GetOrCreateLayerInfo(int layerNumber) {
     LayerInfo layerInfo = layerInfos[layerNumber] ?? (layerInfos[layerNumber] = new LayerInfo());
     return layerInfo;
 }
 static IEnumerable<int> VertConstrainedNodesOfLayer(LayerInfo layerInfo) {
     if (layerInfo != null) {
         foreach (int v in layerInfo.constrainedFromAbove.Keys)
             yield return v;
         foreach (int v in layerInfo.constrainedFromBelow.Keys)
             yield return v;
     }
 }
 internal static bool BelongsToNeighbBlock(int p, LayerInfo layerInfo)
 {
     return(layerInfo != null && (layerInfo.nodeToBlockRoot.ContainsKey(p) || layerInfo.neigBlocks.ContainsKey(p)));
     //p is a root of the block
 }
 static bool NodesAreConstrainedAbove(int leftNode, int rightNode, LayerInfo layerInfo)
 {
     return(NodeIsConstrainedAbove(leftNode, layerInfo) && NodeIsConstrainedAbove(rightNode, layerInfo));
 }
 static bool NodeIsConstrained(int v, SweepMode sweepMode, LayerInfo layerInfo) {
     if (sweepMode == SweepMode.Starting)
         return false;
     return sweepMode == SweepMode.ComingFromAbove && NodeIsConstrainedAbove(v, layerInfo) ||
            sweepMode == SweepMode.ComingFromBelow && NodeIsConstrainedBelow(v, layerInfo);
 }
 internal static bool BelongsToNeighbBlock(int p, LayerInfo layerInfo) {
     return layerInfo != null && (layerInfo.nodeToBlockRoot.ContainsKey(p) || layerInfo.neigBlocks.ContainsKey(p));
     //p is a root of the block
 }
 double GetGapFromNodeNodesConstrainedAbove(int leftNode, int rightNode, LayerInfo layerInfo,
                                                   int layerIndex) {
     double gap = SimpleGapBetweenTwoNodes(leftNode, rightNode);
     leftNode = layerInfo.constrainedFromAbove[leftNode];
     rightNode = layerInfo.constrainedFromAbove[rightNode];
     layerIndex++;
     layerInfo = layerInfos[layerIndex];
     if (layerIndex < LayerArrays.Layers.Length - 1 && NodesAreConstrainedAbove(leftNode, rightNode, layerInfo))
         return Math.Max(gap, GetGapFromNodeNodesConstrainedAbove(leftNode, rightNode, layerInfo, layerIndex));
     return Math.Max(gap, SimpleGapBetweenTwoNodes(leftNode, rightNode));
 }
        static int NodeToBlockRootSoftOnLayerInfo(LayerInfo layerInfo, int node)
        {
            int root;

            return(layerInfo.nodeToBlockRoot.TryGetValue(node, out root) ? root : node);
        }
 static bool NodesAreConstrainedAbove(int leftNode, int rightNode, LayerInfo layerInfo) {
     return NodeIsConstrainedAbove(leftNode, layerInfo) && NodeIsConstrainedAbove(rightNode, layerInfo);
 }
 void AddSeparationConstraintsForFlatEdges(LayerInfo layerInfo, ISolverShell solver) {
     if (layerInfo != null) {
         foreach (var p in layerInfo.flatEdges) {
             int left, right;
             if (LayerArrays.X[p.Item1] < LayerArrays.X[p.Item2]) {
                 left = p.Item1;
                 right = p.Item2;
             } else {
                 left = p.Item2;
                 right = p.Item1;
             }
             if (left == right) continue;
             double gap = GetGap(left, right);
             foreach (IntEdge edge in database.GetMultiedge(p.Item1, p.Item2))
                 solver.AddLeftRightSeparationConstraint(left, right,
                                                         gap + NodeSeparation() +
                                                         (edge.Edge.Label != null ? edge.Edge.Label.Width : 0));
         }
     }
 }
 static bool NodeIsConstrainedAbove(int v, LayerInfo layerInfo) {
     if (layerInfo == null)
         return false;
     return layerInfo.constrainedFromAbove.ContainsKey(v);
 }