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; }
static bool NodeIsConstrainedAbove(int v, LayerInfo layerInfo) { if (layerInfo == null) { return(false); } return(layerInfo.constrainedFromAbove.ContainsKey(v)); }
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); }