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)); }
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); } }
/// <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); }
private void CreateDictionaryOfSameLayerRepresentatives() { BasicGraphOnEdges <IntPair> graphOfSameLayers = CreateGraphOfSameLayers(); foreach (var comp in ConnectedComponentCalculator <IntPair> .GetComponents(graphOfSameLayers)) { GlueSameLayerNodesOfALayer(comp); } }
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)); }
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; }
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); } } }
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); } }
/// <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]))); }
/// <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); }
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; } } } }
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); }
internal NetworkSimplex(BasicGraphOnEdges <PolyIntEdge> graph, CancelToken cancelToken) { this.graph = CreateGraphWithIEEdges(graph); inTree = new bool[graph.NodeCount]; NetworkCancelToken = cancelToken; }
private IEnumerable <IEdge> GetFeedbackSet() { this.gluedIntGraph = CreateGluedGraph(); return(UnglueIntPairs(CycleRemoval <IntPair> .GetFeedbackSetWithConstraints(gluedIntGraph, this.GluedUpDownIntConstraints)));//avoiding lazy evaluation }
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]]; } } }
internal NetworkSimplexForGeneralGraph(BasicGraph <Node, PolyIntEdge> graph, CancelToken cancelObject) { this.graph = graph; this.Cancel = cancelObject; }
/// <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); }
internal Succ(BasicGraphOnEdges <PolyIntEdge> g, int v) { this.graph = g; this.vert = v; }
/// <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; }
internal LongestPathLayering(BasicGraphOnEdges <PolyIntEdge> graph) { this.graph = graph; }