/// <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 BasicGraph <IntEdge>(from pair in horizontalConstraints.VerticalInts select new IntEdge(pair.Item1, pair.Item2)); var verticalComponents = ConnectedComponentCalculator <IntEdge> .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); }
void UniteConnectedPreGraphs(ref List <PreGraph> preGraphs) { BasicGraph <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); } }
internal PhyloTreeLayoutCalclulation(PhyloTree phyloTreeP, SugiyamaLayoutSettings settings, BasicGraph<Node, IntEdge> intGraphP, Database dataBase) { this.dataBase = dataBase; this.tree = phyloTreeP; this.LayoutSettings = settings; this.intGraph = intGraphP; originalNodeToGridLayerIndices = new int[intGraph.Nodes.Count]; }
public override void Solve(IOManager io) { var nodeCount = io.ReadInt(); var edgeCount = io.ReadInt(); var graph = new BasicGraph(nodeCount); var indegrees = new int[graph.NodeCount]; for (int i = 0; i < edgeCount; i++) { var s = io.ReadInt(); var t = io.ReadInt(); s--; t--; graph.AddEdge(s, t); indegrees[t]++; } var result = double.MaxValue; for (int block = 0; block < graph.NodeCount; block++) { result.ChangeMin(GetExpectation(block)); } io.WriteLine(result); double GetExpectation(int block) { Span <double> dp = stackalloc double[graph.NodeCount]; dp[^ 1] = 0;
public override IEnumerable <object> Solve(TextReader inputStream) { var nodeCount = inputStream.ReadInt(); tree = new BasicGraph(nodeCount); counts = new int[nodeCount]; results = new int[nodeCount]; for (int i = 0; i < nodeCount - 1; i++) { var(a, b) = inputStream.ReadValue <int, int>(); a--; b--; counts[a]++; counts[b]++; tree.AddEdge(new BasicEdge(a, b)); tree.AddEdge(new BasicEdge(b, a)); } points = new Queue <int>(inputStream.ReadIntArray().OrderBy(i => i)); var total = points.Take(points.Count - 1).Sum(); Bfs(); yield return(total); yield return(results.Join(' ')); }
internal static RectangleNode <Polyline> 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 BasicGraph <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)); }
public override IEnumerable <object> Solve(TextReader inputStream) { var n = inputStream.ReadInt(); maxValues = Enumerable.Repeat(int.MaxValue, n).ToArray(); minValues = Enumerable.Repeat(int.MinValue, n).ToArray(); graph = new BasicGraph(n); for (int i = 0; i < n - 1; i++) { var(a, b) = inputStream.ReadValue <int, int>(); a--; b--; graph.AddEdge(new BasicEdge(a, b)); graph.AddEdge(new BasicEdge(b, a)); } var starts = new List <int>(); var k = inputStream.ReadInt(); for (int i = 0; i < k; i++) { var(v, p) = inputStream.ReadValue <int, int>(); v--; maxValues[v] = p; minValues[v] = p; starts.Add(v); } if (!CheckEvenOdd(starts[0], -1, minValues[starts[0]])) { yield return("No"); yield break; } //Shuffle(starts); foreach (var start in starts) { Dfs(start, -1, maxValues[start] + 1, minValues[start] - 1); } for (int i = 0; i < maxValues.Length; i++) { if (maxValues[i] < minValues[i]) { yield return("No"); yield break; } } yield return("Yes"); foreach (var value in minValues) { yield return(value); } }
internal ConstrainedOrdering( GeometryGraph geomGraph, BasicGraph<Node, IntEdge> basicIntGraph, int[] layering, Dictionary<Node, int> nodeIdToIndex, Database database, SugiyamaLayoutSettings settings) { this.settings = settings; horizontalConstraints = settings.HorizontalConstraints; horizontalConstraints.PrepareForOrdering(nodeIdToIndex, layering); geometryGraph = geomGraph; this.database = database; intGraph = basicIntGraph; initialLayering = layering; //this has to be changed only to insert layers that are needed if (NeedToInsertLayers(layering)) { for (int i = 0; i < layering.Length; i++) layering[i] *= 2; LayersAreDoubled = true; numberOfLayers = -1; } PrepareProperLayeredGraphAndFillLayerInfos(); adjSwapper = new AdjacentSwapsWithConstraints( LayerArrays, HasCrossWeights(), ProperLayeredGraph, layerInfos); }
private static async void moveEdge(BasicGraph sender, double x, double y) { try { Point2 coords = await sender.RequestTransformedEventPosition(x, y); Edge edge = sender.graphService.CurrentGraphModel.ActiveEdge; var diff = edge.Edgemiddle - new Vector2((float)coords.X, (float)coords.Y); var dir = Vector2.Normalize(diff); var dirdiff = dir - edge.Direction; var dot = Vector2.Dot(edge.Direction, dir); if (dot > 0) { if (edge.curveScale < edge.curveScaleUpperBound) { edge.curveScale += 0.1f; } } else if (edge.curveScale > edge.curveScaleLowerBound) { edge.curveScale -= 0.1f; } } catch { } }
static void graphTestSuite() { GraphNode <int> startNode = new GraphNode <int>(0); BasicGraph <int> testGraph = new BasicGraph <int>(startNode); var temp = new GraphNode <int>(1); temp.addConnection(testGraph.AllNodes[0], 10); temp = new GraphNode <int>(2); temp.addConnection(testGraph.AllNodes[0], 8); temp.addConnection(testGraph.AllNodes[1], 10); temp = new GraphNode <int>(3); temp.addConnection(testGraph.AllNodes[0], 9); temp.addConnection(testGraph.AllNodes[1], 5); temp.addConnection(testGraph.AllNodes[2], 8); temp = new GraphNode <int>(4); temp.addConnection(testGraph.AllNodes[0], 7); temp.addConnection(testGraph.AllNodes[1], 6); temp.addConnection(testGraph.AllNodes[2], 9); temp.addConnection(testGraph.AllNodes[3], 6); Solution bestPath = TSP.branchandBound(testGraph); Console.WriteLine("shortest distance is {0} via route {1}", bestPath.minCost, String.Join("-", bestPath.path)); }
public void RerootingTestABC160ExampleF() { var inputs = @"8 1 2 2 3 3 4 3 5 3 6 6 7 6 8".Split(Environment.NewLine); var n = int.Parse(inputs[0]); var graph = new BasicGraph(n); foreach (var input in inputs.Skip(1).Select(s => s.Split(' ').Select(s => int.Parse(s) - 1).ToArray())) { graph.AddEdge(input[0], input[1]); graph.AddEdge(input[1], input[0]); } var rerooting = new Rerooting <BasicEdge, DPState>(graph); var result = rerooting.Solve().Select(r => r.Count.Value); var expected = new int[] { 40, 280, 840, 120, 120, 504, 72, 72 }; Assert.Equal(expected, result); }
internal void Initialize(BasicGraph <Node, IntEdge> intGraph) { BaseGraph = intGraph; if (BaseGraph.Edges.Count > 0) { var edgesGoingDown = from edge in BaseGraph.Edges where edge.LayerEdges != null select edge; if (edgesGoingDown.Any()) { totalNumberOfNodes = (from edge in edgesGoingDown from layerEdge in edge.LayerEdges select Math.Max(layerEdge.Source, layerEdge.Target) + 1).Max(); } else { totalNumberOfNodes = intGraph.NodeCount; } } else { totalNumberOfNodes = intGraph.NodeCount; } if (ExistVirtualNodes(BaseGraph.Edges)) { firstVirtualNode = (from edge in BaseGraph.Edges where edge.LayerEdges != null && edge.LayerEdges.Count > 1 let source = edge.Source from layerEdge in edge.LayerEdges let layerEdgeSource = layerEdge.Source where layerEdge.Source != source select layerEdgeSource).Min(); } else { firstVirtualNode = BaseGraph.NodeCount; totalNumberOfNodes = BaseGraph.NodeCount; } virtualNodesToInEdges = new LayerEdge[totalNumberOfNodes - FirstVirtualNode]; virtualNodesToOutEdges = new LayerEdge[totalNumberOfNodes - FirstVirtualNode]; foreach (IntEdge e in BaseGraph.Edges) { if (e.LayerSpan > 0) { foreach (LayerEdge le in e.LayerEdges) { if (le.Target != e.Target) { virtualNodesToInEdges[le.Target - FirstVirtualNode] = le; } if (le.Source != e.Source) { virtualNodesToOutEdges[le.Source - FirstVirtualNode] = le; } } } } }
private static void toggleActiveStateNode(BasicGraph sender, Node node) { if (sender.graphService.CurrentGraphModel.ActiveEdge != null) { sender.graphService.CurrentGraphModel.ActiveEdge.IsActive = false; } var activeNode = sender.graphService.CurrentGraphModel.ActiveNode; if (activeNode != null) { if (activeNode.Id == node.Id) { node.IsActive = false; } else { activeNode.IsActive = false; node.IsActive = true; } } else { node.IsActive = true; } }
List <int> TopologicalSort(BasicGraph graph, int[] inDegrees) { var sorted = new List <int>(); var queue = new Queue <int>(); for (int i = 0; i < inDegrees.Length; i++) { if (inDegrees[i] == 0) { queue.Enqueue(i); } } while (queue.Count > 0) { var current = queue.Dequeue(); sorted.Add(current); foreach (var edge in graph[current]) { inDegrees[edge.To.Index]--; if (inDegrees[edge.To.Index] == 0) { queue.Enqueue(edge.To.Index); } } } return(sorted); }
private bool CreateConvexHulls() { var found = false; var graph = new BasicGraph <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); }
/// <summary> /// constructor /// </summary> /// <param name="layeredGraph"></param> /// <param name="la"></param> /// <param name="database"></param> /// <param name="intGraphP"></param> LayerInserter( ProperLayeredGraph layeredGraph, LayerArrays la, Database database, BasicGraph<Node, IntEdge> intGraphP) { this.la = la; this.database = database; this.layeredGraph = layeredGraph; this.intGraph = intGraphP; }
public override void Solve(IOManager io) { var n = io.ReadInt(); var tree = new BasicGraph(n); for (int i = 0; i < n - 1; i++) { var u = io.ReadInt(); var v = io.ReadInt(); u--; v--; tree.AddEdge(u, v); tree.AddEdge(v, u); } var lca = new LowestCommonAncester(tree); var queries = io.ReadInt(); for (int q = 0; q < queries; q++) { var a = io.ReadInt() - 1; var b = io.ReadInt() - 1; io.WriteLine(lca.Depths[a] + lca.Depths[b] - 2 * lca.Depths[lca.GetLcaNode(a, b)] + 1); } }
///// <summary> ///// Computes distances between a selected set of nodes and all nodes. ///// Pivot nodes are selected with maxmin strategy (first at random, later ///// ones to maximize distances to all previously selected ones). ///// </summary> ///// <param name="graph">A graph.</param> ///// <param name="directed">Whether shortest paths are directed.</param> ///// <param name="numberOfPivots">Number of pivots.</param> ///// <returns>A square matrix with shortest path distances.</returns> //public static double[][] PivotUniformDistances(GeometryGraph graph, bool directed, int numberOfPivots) { // double[][] d = new double[numberOfPivots][]; // Node[] nodes = new Node[graph.Nodes.Count]; // graph.Nodes.CopyTo(nodes, 0); // double[] min = new double[graph.Nodes.Count]; // for (int i = 0; i < min.Length; i++) { // min[i] = Double.PositiveInfinity; // } // System.Console.Write("pivoting "); // Node pivot = nodes[0]; // for (int i = 0; i < numberOfPivots; i++) { // System.Console.Write("."); // d[i] = SingleSourceUniformDistances(graph, pivot, directed); // int argmax = 0; // for (int j = 0; j < d[i].Length; j++) { // min[j] = Math.Min(min[j], d[i][j]); // if (min[j] > min[argmax]) // argmax = j; // } // pivot = nodes[argmax]; // } // System.Console.WriteLine(); // return d; //} ///// <summary> ///// Determines whether the graph is (weakly) connected, that is, ///// if there is a path connecting every two nodes. ///// </summary> ///// <param name="graph">A graph.</param> ///// <returns>true iff the graph is connected.</returns> //public static bool IsConnected(GeometryGraph graph) { // IEnumerator<Node> enumerator = graph.Nodes.GetEnumerator(); // enumerator.MoveNext(); // Node node=enumerator.Current; // double[] distances=SingleSourceUniformDistances(graph, node, false); // for (int i = 0; i < distances.Length; i++) { // if (distances[i] == Double.PositiveInfinity) return false; // } // return true; //} /// <summary> /// Gives graphs representing the connected components of the graph /// </summary> /// <param name="graph">A graph.</param> /// <param name="nodeToNodeIndex">the dictionary: node -> node index in the NodeMap</param> /// <returns>An array of connected components.</returns> internal static GeometryGraph[] ComponentGraphs(GeometryGraph graph, Dictionary <Node, int> nodeToNodeIndex) { Node[] nodes = new Node[graph.Nodes.Count]; graph.Nodes.CopyTo(nodes, 0); BasicGraph <IntPair> basicGraph = new BasicGraph <IntPair>( from edge in graph.Edges where !(edge.Source is Cluster || edge.Target is Cluster) select new IntPair(nodeToNodeIndex[edge.Source], nodeToNodeIndex[edge.Target]), graph.Nodes.Count); List <IEnumerable <int> > comps = new List <IEnumerable <int> >(ConnectedComponentCalculator <IntPair> .GetComponents(basicGraph)); if (comps.Count == 1) { return new GeometryGraph[] { graph } } ; GeometryGraph[] ret = new GeometryGraph[comps.Count]; int i = 0; foreach (var comp in comps) { ret[i++] = GeomGraphFromBasicGraph(comp, nodes); } return(ret); }
public override IEnumerable <object> Solve(TextReader inputStream) { Modular.InitializeCombinationTable(); var nodesCount = inputStream.ReadInt(); graph = new BasicGraph(nodesCount); for (int i = 0; i < nodesCount - 1; i++) { var(a, b) = inputStream.ReadValue <int, int>(); a--; b--; graph.AddEdge(new BasicEdge(a, b)); graph.AddEdge(new BasicEdge(b, a)); } dpStates = new DPState[nodesCount]; for (int i = 0; i < dpStates.Length; i++) { dpStates[i] = new DPState(new Modular(1), 0); } var rerooting = new Rerooting <BasicNode, BasicEdge, DPState>(graph); var results = rerooting.Solve().Select(r => r.Count.Value); foreach (var result in results) { yield return(result); } }
internal PhyloTreeLayoutCalclulation(PhyloTree phyloTreeP, SugiyamaLayoutSettings settings, BasicGraph <Node, IntEdge> intGraphP, Database dataBase) { this.dataBase = dataBase; this.tree = phyloTreeP; this.LayoutSettings = settings; this.intGraph = intGraphP; originalNodeToGridLayerIndices = new int[intGraph.Nodes.Count]; }
static internal void InsertPaths( ref ProperLayeredGraph layeredGraph, ref LayerArrays la, Database db, BasicGraph<Node, IntEdge> intGraphP) { EdgePathsInserter li = new EdgePathsInserter(layeredGraph, la, db, intGraphP); li.InsertPaths(); layeredGraph = li.NLayeredGraph; la = li.Nla; }
private static void activateDragNode(BasicGraph sender, Node target) { if (((BasicGraph)sender).graphService.CurrentGraphModel.ActiveNode != null && target.IsActive) { sender.NodeDragStarted = true; sender.DisablePan(); } }
private void CreateDictionaryOfSameLayerRepresentatives() { BasicGraph <IntPair> graphOfSameLayers = CreateGraphOfSameLayers(); foreach (var comp in ConnectedComponentCalculator <IntPair> .GetComponents(graphOfSameLayers)) { GlueSameLayerNodesOfALayer(comp); } }
public override IEnumerable <object> Solve(TextReader inputStream) { var(nodeCount, takahashiStart, aokiStart) = inputStream.ReadValue <int, int, int>(); takahashiStart--; aokiStart--; var tree = new BasicGraph(nodeCount); for (int i = 0; i < nodeCount - 1; i++) { var(a, b) = inputStream.ReadValue <int, int>(); a--; b--; tree.AddEdge(new BasicEdge(a, b)); tree.AddEdge(new BasicEdge(b, a)); } var takahashiDistances = GetDistances(takahashiStart); var aokiDistances = GetDistances(aokiStart); var result = 0; for (int i = 0; i < nodeCount; i++) { if (takahashiDistances[i] < aokiDistances[i]) { result = Math.Max(result, aokiDistances[i]); } } yield return(result - 1); int[] GetDistances(int startNode) { const int Inf = 1 << 28; var todo = new Queue <int>(); var distances = Enumerable.Repeat(Inf, nodeCount).ToArray(); todo.Enqueue(startNode); distances[startNode] = 0; while (todo.Count > 0) { var current = todo.Dequeue(); foreach (var edge in tree[current]) { var next = edge.To.Index; if (distances[next] == Inf) { distances[next] = distances[current] + 1; todo.Enqueue(next); } } } return(distances); } }
///// <summary> ///// the entry point of the class ///// </summary> ///// <param name="layeredGraph"></param> ///// <param name="la"></param> ///// <param name="db"></param> static internal void InsertLayers( ref ProperLayeredGraph layeredGraph, ref LayerArrays la, Database db, BasicGraph<Node, IntEdge> intGraphP) { LayerInserter li = new LayerInserter(layeredGraph, la, db, intGraphP); li.InsertLayers(); layeredGraph = li.NLayeredGraph; la = li.Nla.DropEmptyLayers(); }
public void GetQuality_Success() { var options = new BaseOptions(numberOfIterations: 100, numberOfRegions: 3, alfa: 1, beta: 5, ro: 0.6, delta: 0.1D); var graph = new BasicGraph(null, null); var rnd = new Random(Environment.TickCount); var aspg = new Aspg(options, graph, rnd); //var quality = aspg.GetQuality(); }
static internal void InsertPaths( ref ProperLayeredGraph layeredGraph, ref LayerArrays la, Database db, BasicGraph <Node, IntEdge> intGraphP) { EdgePathsInserter li = new EdgePathsInserter(layeredGraph, la, db, intGraphP); li.InsertPaths(); layeredGraph = li.NLayeredGraph; la = li.Nla; }
private static async void moveNode(BasicGraph sender, double x, double y) { try { Point2 coords = await sender.RequestTransformedEventPosition(x, y); setNodePosition(sender.graphService.CurrentGraphModel.ActiveNode, coords); } catch { } }
public LowestCommonAncester(BasicGraph graph, int root = 0) { if (graph.NodeCount == 0) { throw new ArgumentException(); } _ceilLog2 = BitOperations.Log2((uint)(graph.NodeCount - 1)) + 1; _parents = new int[_ceilLog2, graph.NodeCount]; for (int i = 0; i < _ceilLog2; i++) { for (int j = 0; j < graph.NodeCount; j++) { _parents[i, j] = -1; } } _depths = new int[graph.NodeCount]; _depths.AsSpan().Fill(-1); Dfs(root, -1, 0); Initialize(); void Dfs(int current, int parent, int depth) { _parents[0, current] = parent; _depths[current] = depth; foreach (var next in graph[current]) { if (next != parent) { Dfs(next, current, depth + 1); } } } void Initialize() { for (int pow = 0; pow + 1 < _ceilLog2; pow++) { for (int v = 0; v < _depths.Length; v++) { if (_parents[pow, v] < 0) { _parents[pow + 1, v] = -1; } else { _parents[pow + 1, v] = _parents[pow, _parents[pow, v]]; } } } } }
static BasicGraph <IntEdge> CreateGraphWithIEEdges(BasicGraph <IntEdge> bg) { List <IntEdge> ieEdges = new List <IntEdge>(); foreach (IntEdge e in bg.Edges) { ieEdges.Add(new NetworkEdge(e)); } return(new BasicGraph <IntEdge>(ieEdges, bg.NodeCount)); }
public void ReadVerticesWeights_CorrectCount_Success() { var graph = new BasicGraph("baba.txt", "baba.txt"); using (var stream = GenerateStreamFromString(BasicVericesWeights)) { graph.ReadVerticesWeights(stream); } Assert.AreEqual(9, graph.VerticesWeights.Count); }
public void ReadEdgesWeights_CorrectFormat_Fail() { var graph = new BasicGraph("baba.txt", "baba.txt"); using (var stream = GenerateStreamFromString(BasicEdgesWeights)) { graph.ReadEdgesWeights(stream); } Assert.AreEqual(3, graph.EdgesWeights[0, 1]); }
void CreateProperLayeredGraph() { IEnumerable <IntEdge> edges = CreatePathEdgesOnIntGraph(); var nodeCount = Math.Max(intGraph.NodeCount, BasicGraph <Node, IntEdge> .VertexCount(edges)); var baseGraph = new BasicGraph <Node, IntEdge>(edges, nodeCount) { Nodes = intGraph.Nodes }; ProperLayeredGraph = new ProperLayeredGraph(baseGraph); }
internal Routing(SugiyamaLayoutSettings settings, GeometryGraph originalGraph, Database dbP, LayerArrays yLayerArrays, ProperLayeredGraph properLayeredGraph, BasicGraph<Node, IntEdge> intGraph ) { this.settings = settings; OriginalGraph = originalGraph; Database = dbP; ProperLayeredGraph = properLayeredGraph; LayerArrays = yLayerArrays; IntGraph = intGraph; }
/// <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 BasicGraph<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> /// it is a special recovery constructor to recreate the engine from the recovery engine /// </summary> internal LayeredLayoutEngine(LayerArrays engineLayerArrays, GeometryGraph originalGraph, ProperLayeredGraph properLayeredGraph, SugiyamaLayoutSettings sugiyamaSettings, Database database, BasicGraph<Node, IntEdge> intGraph, Dictionary<Node, int> nodeIdToIndex, BasicGraph<Node, IntEdge> gluedDagSkeletonForLayering, bool layersAreDoubled, ConstrainedOrdering constrainedOrdering, bool brandes, XLayoutGraph xLayoutGraph) { this.engineLayerArrays = engineLayerArrays; this.originalGraph = originalGraph; this.properLayeredGraph = properLayeredGraph; this.sugiyamaSettings = sugiyamaSettings; this.database = database; IntGraph = intGraph; this.nodeIdToIndex = nodeIdToIndex; GluedDagSkeletonForLayering = gluedDagSkeletonForLayering; LayersAreDoubled = layersAreDoubled; this.constrainedOrdering = constrainedOrdering; Brandes = brandes; anchors = database.anchors; this.xLayoutGraph = xLayoutGraph; }
/// <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 BasicGraph<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; }
internal void Initialize(BasicGraph<Node, IntEdge> intGraph) { BaseGraph = intGraph; if (BaseGraph.Edges.Count > 0) { var edgesGoingDown = from edge in BaseGraph.Edges where edge.LayerEdges != null select edge; if(edgesGoingDown.Any() ) totalNumberOfNodes= (from edge in edgesGoingDown from layerEdge in edge.LayerEdges select Math.Max(layerEdge.Source, layerEdge.Target) + 1).Max(); else totalNumberOfNodes = intGraph.NodeCount; } else totalNumberOfNodes = intGraph.NodeCount; if (ExistVirtualNodes(BaseGraph.Edges)) { firstVirtualNode = (from edge in BaseGraph.Edges where edge.LayerEdges != null && edge.LayerEdges.Count > 1 let source = edge.Source from layerEdge in edge.LayerEdges let layerEdgeSource = layerEdge.Source where layerEdge.Source != source select layerEdgeSource).Min(); } else { firstVirtualNode = BaseGraph.NodeCount; totalNumberOfNodes = BaseGraph.NodeCount; } virtualNodesToInEdges = new LayerEdge[totalNumberOfNodes - FirstVirtualNode]; virtualNodesToOutEdges = new LayerEdge[totalNumberOfNodes - FirstVirtualNode]; foreach (IntEdge e in BaseGraph.Edges) if (e.LayerSpan > 0) foreach (LayerEdge le in e.LayerEdges) { if (le.Target != e.Target) virtualNodesToInEdges[le.Target - FirstVirtualNode] = le; if (le.Source != e.Source) virtualNodesToOutEdges[le.Source - FirstVirtualNode] = le; } }
internal static void CalculateAnchorSizes(Database database, out Anchor[] anchors, ProperLayeredGraph properLayeredGraph, GeometryGraph originalGraph, BasicGraph<Node, IntEdge> intGraph, SugiyamaLayoutSettings settings) { database.Anchors = anchors = new Anchor[properLayeredGraph.NodeCount]; for (int i = 0; i < anchors.Length; i++) anchors[i] = new Anchor(settings.LabelCornersPreserveCoefficient); //go over the old vertices for (int i = 0; i < originalGraph.Nodes.Count; i++) CalcAnchorsForOriginalNode(i, intGraph, anchors, database, settings); //go over virtual vertices foreach (IntEdge intEdge in database.AllIntEdges) if (intEdge.LayerEdges != null) { foreach (LayerEdge layerEdge in intEdge.LayerEdges) { int v = layerEdge.Target; if (v != intEdge.Target) { Anchor anchor = anchors[v]; if (!database.MultipleMiddles.Contains(v)) { anchor.LeftAnchor = anchor.RightAnchor = VirtualNodeWidth/2.0f; anchor.TopAnchor = anchor.BottomAnchor = VirtualNodeHeight(settings)/2.0f; } else { anchor.LeftAnchor = anchor.RightAnchor = VirtualNodeWidth*4; anchor.TopAnchor = anchor.BottomAnchor = VirtualNodeHeight(settings)/2.0f; } } } //fix label vertices if (intEdge.HasLabel) { int lj = intEdge.LayerEdges[intEdge.LayerEdges.Count/2].Source; Anchor a = anchors[lj]; double w = intEdge.LabelWidth, h = intEdge.LabelHeight; a.RightAnchor = w; a.LeftAnchor = VirtualNodeWidth*8; if (a.TopAnchor < h/2.0) a.TopAnchor = a.BottomAnchor = h/2.0; a.LabelToTheRightOfAnchorCenter = true; } } }
/// <summary> /// constructor /// </summary> internal LayeredLayoutEngine(GeometryGraph originalGraph, BasicGraph<Node, IntEdge> graph, Dictionary<Node, int> nodeIdToIndex, SugiyamaLayoutSettings settings) { if (originalGraph != null) { this.originalGraph = originalGraph; sugiyamaSettings = settings; IntGraph = graph; Database = new Database(); this.nodeIdToIndex = nodeIdToIndex; foreach (IntEdge e in graph.Edges) database.RegisterOriginalEdgeInMultiedges(e); #if REPORTING if (sugiyamaSettings.Reporting && SugiyamaLayoutLogger == null) SugiyamaLayoutLogger = new SugiyamaLayoutLogger(); #endif CycleRemoval(); } }
/// <summary> /// Calculates distances from graph vertices to some selected set of vertices; accepting states. /// </summary> /// <param name="acceptingStates"></param> /// <returns></returns> internal int[] GetDistanceToAcceptingStates(int[] acceptingStates) { if(MustEdges==null) return new int[0]; //calculate distances from accepting states //by running shortest paths on the reversed graph Edge[] reversedEdges=new Edge[MustEdges.Length]; for(int i=0;i<reversedEdges.Length;i++){ Edge l=MustEdges[i]; reversedEdges[i]=new Edge(l.target,l.source,l.label,l.weight); } BasicGraph basicGraph=new BasicGraph(0, reversedEdges); MultipleSourcesShortestPaths mssp=new MultipleSourcesShortestPaths(basicGraph,acceptingStates); mssp.Calculate(); //now we have the distance from acceptingStates to any state in mssp.GetDistTo(state) int[] ret=new int[NumberOfVertices]; for(int i=0;i<NumberOfVertices;i++) ret[i]=mssp.GetDistTo(i); return ret; }
/// <summary> /// /// </summary> /// <returns>the height of the graph+spaceBeforeMargins</returns> internal static void CalcInitialYAnchorLocations(LayerArrays layerArrays, double spaceBeforeMargins, GeometryGraph originalGraph, Database database, BasicGraph<IntEdge> intGraph, SugiyamaLayoutSettings settings, bool layersAreDoubled) { Anchor[] anchors = database.Anchors; double ymax = originalGraph.Margins + spaceBeforeMargins; //setting up y coord - going up by y-layers int i = 0; foreach (var yLayer in layerArrays.Layers) { double bottomAnchorMax = 0; double topAnchorMax = 0; foreach (int j in yLayer) { Anchor p = anchors[j]; if (p.BottomAnchor > bottomAnchorMax) bottomAnchorMax = p.BottomAnchor; if (p.TopAnchor > topAnchorMax) topAnchorMax = p.TopAnchor; } MakeVirtualNodesHigh(yLayer, bottomAnchorMax, topAnchorMax, originalGraph.Nodes.Count, database.Anchors); double flatEdgesHeight = SetFlatEdgesForLayer(database, layerArrays, i, intGraph, settings, ymax); double y = ymax + bottomAnchorMax + flatEdgesHeight; foreach (int j in yLayer) anchors[j].Y = y; double layerSep = settings.ActualLayerSeparation(layersAreDoubled); ymax = y + topAnchorMax + layerSep; i++; } SetFlatEdgesForLayer(database, layerArrays, i, intGraph, settings, ymax); }
static void CalcAnchorsForOriginalNode(int i, BasicGraph<Node, IntEdge> intGraph, Anchor[] anchors, Database database, SugiyamaLayoutSettings settings) { double leftAnchor = 0; double rightAnchor = leftAnchor; double topAnchor = 0; double bottomAnchor = topAnchor; //that's what we would have without the label and multiedges if (intGraph.Nodes != null) { Node node = intGraph.Nodes[i]; ExtendStandardAnchors(ref leftAnchor, ref rightAnchor, ref topAnchor, ref bottomAnchor, node, settings); } RightAnchorMultiSelfEdges(i, ref rightAnchor, ref topAnchor, ref bottomAnchor, database, settings); double hw = settings.MinNodeWidth/2; if (leftAnchor < hw) leftAnchor = hw; if (rightAnchor < hw) rightAnchor = hw; double hh = settings.MinNodeHeight/2; if (topAnchor < hh) topAnchor = hh; if (bottomAnchor < hh) bottomAnchor = hh; anchors[i] = new Anchor(leftAnchor, rightAnchor, topAnchor, bottomAnchor, intGraph.Nodes[i], settings.LabelCornersPreserveCoefficient) {Padding = intGraph.Nodes[i].Padding}; #if TEST_MSAGL anchors[i].UserData = intGraph.Nodes[i].UserData; #endif }
static double SetFlatEdgesForLayer(Database database, LayerArrays layerArrays, int i, BasicGraph<IntEdge> intGraph, SugiyamaLayoutSettings settings, double ymax) { double flatEdgesHeight = 0; if (i > 0) { //looking for flat edges on the previous level //we stack labels of multiple flat edges on top of each other IEnumerable<IntPair> flatPairs = GetFlatPairs(layerArrays.Layers[i - 1], layerArrays.Y, intGraph); if (flatPairs.Any()) { double dyOfFlatEdge = settings.LayerSeparation/3; double ym = ymax; flatEdgesHeight = (from pair in flatPairs select SetFlatEdgesLabelsHeightAndPositionts(pair, ym, dyOfFlatEdge, database)). Max(); } } return flatEdgesHeight; }
internal ProperLayeredGraph(BasicGraph<Node, IntEdge> intGraph) { Initialize(intGraph); }
/// <summary> /// Returns a strategy to reach targets from a vertex. /// </summary> /// <param name="vertex"></param> /// <returns></returns> internal Strategy[] GetStrategyReachableFromVertex(int vertex) { Strategy [] strategies=this.GetStrategies(); if(VertIsNondet(vertex)) throw new ArgumentException("vertex is a choice point"); //ArrayList links=new ArrayList(); HSet linkSet=new HSet(); foreach(Strategy s in strategies) if(s.edge!=null){ linkSet.Insert(s.edge); if(VertIsNondet( s.edge.target)) foreach(Edge l in graph.EdgesAtVertex(s.edge.target)) linkSet.Insert(l); } BasicGraph bg=new BasicGraph(0, linkSet.ToArray(typeof(Edge)) ); bool []reachables=bg.GetReachableArray(vertex); for(int i=0;i<reachables.Length;i++){ if(reachables[i]==false) strategies[i].edge=null; } return strategies; }
internal IEnumerable<IEdge> GetFeedbackSet(BasicGraph<Node, IntEdge> intGraphPar, Dictionary<Node, int> nodeIdToIndexPar) { this.nodeIdToIndex = nodeIdToIndexPar; this.intGraph = intGraphPar; this.maxRepresentative = -1; this.minRepresentative = -1; CreateIntegerConstraints(); GlueTogetherSameConstraintsMaxAndMin(); AddMaxMinConstraintsToGluedConstraints(); RemoveCyclesFromGluedConstraints(); return GetFeedbackSet(); }
void Init(GeometryGraph geometryGraph) { nodeIdToIndex = new Dictionary<Node, int>(); IList<Node> nodes = geometryGraph.Nodes; InitNodesToIndex(nodes); IntEdge[] intEdges = CreateIntEdges(geometryGraph); IntGraph = new BasicGraph<Node, IntEdge>(intEdges, geometryGraph.Nodes.Count) { Nodes = nodes }; originalGraph = geometryGraph; if (sugiyamaSettings == null) sugiyamaSettings = new SugiyamaLayoutSettings(); CreateDatabaseAndRegisterIntEdgesInMultiEdges(); }
/// <summary> /// Simpler constructor which initializes the internal graph representation automatically /// </summary> /// <param name="originalGraph"></param> /// <param name="settings"></param> internal LayeredLayoutEngine(GeometryGraph originalGraph, SugiyamaLayoutSettings settings) { if (originalGraph != null) { //enumerate the nodes - maps node indices to strings nodeIdToIndex = new Dictionary<Node, int>(); IList<Node> nodes = originalGraph.Nodes; int index = 0; foreach (Node n in nodes) { nodeIdToIndex[n] = index; index++; } var edges = originalGraph.Edges; var intEdges = new IntEdge[edges.Count]; int i = 0; foreach(var edge in edges){ if (edge.Source == null || edge.Target == null) throw new InvalidOperationException(); //"creating an edge with null source or target"); var intEdge = new IntEdge(nodeIdToIndex[edge.Source], nodeIdToIndex[edge.Target], edge); intEdges[i] = intEdge; i++; } IntGraph = new BasicGraph<Node, IntEdge>(intEdges, originalGraph.Nodes.Count) {Nodes = nodes}; this.originalGraph = originalGraph; sugiyamaSettings = settings; Database = new Database(); foreach (IntEdge e in IntGraph.Edges) database.RegisterOriginalEdgeInMultiedges(e); CycleRemoval(); } }
internal NetworkSimplexForGeneralGraph(BasicGraph<Node, IntEdge> graph, CancelToken cancelObject) { this.graph = graph; this.Cancel = cancelObject; }
/// <summary> /// /// </summary> /// <returns>the height of the graph+spaceBeforeMargins</returns> internal static void CalcInitialYAnchorLocations(LayerArrays layerArrays, double spaceBeforeMargins, GeometryGraph originalGraph, Database database, BasicGraph<IntEdge> intGraph, SugiyamaLayoutSettings settings, bool layersAreDoubled) { Anchor[] anchors = database.Anchors; double ymax = originalGraph.Margins + spaceBeforeMargins; //setting up y coord - going up by y-layers int i = 0; foreach (var yLayer in layerArrays.Layers) { double bottomAnchorMax = 0; double topAnchorMax = 0; foreach (int j in yLayer) { Anchor p = anchors[j]; if (p.BottomAnchor > bottomAnchorMax) bottomAnchorMax = p.BottomAnchor; if (p.TopAnchor > topAnchorMax) topAnchorMax = p.TopAnchor; } MakeVirtualNodesTall(yLayer, bottomAnchorMax, topAnchorMax, originalGraph.Nodes.Count, database.Anchors); double flatEdgesHeight = SetFlatEdgesForLayer(database, layerArrays, i, intGraph, settings, ymax); double layerCenter = ymax + bottomAnchorMax + flatEdgesHeight; double layerTop = layerCenter + topAnchorMax; if (NeedToSnapTopsToGrid(settings)) { layerTop += SnapDeltaUp(layerTop, settings.GridSizeByY); foreach (int j in yLayer) anchors[j].Top = layerTop; } else if (NeedToSnapBottomsToGrid(settings)) { double layerBottom = layerCenter - bottomAnchorMax; layerBottom += SnapDeltaUp(layerBottom, layerBottom); foreach (int j in yLayer) { anchors[j].Bottom = layerBottom; layerTop = Math.Max(anchors[j].Top, layerTop); } } else foreach (int j in yLayer) anchors[j].Y = layerCenter; double layerSep = settings.ActualLayerSeparation(layersAreDoubled); ymax = layerTop + layerSep; i++; } // for the last layer SetFlatEdgesForLayer(database, layerArrays, i, intGraph, settings, ymax); }
void CreateProperLayeredGraph() { IEnumerable<IntEdge> edges = CreatePathEdgesOnIntGraph(); var nodeCount = Math.Max(intGraph.NodeCount, BasicGraph<Node, IntEdge>.VertexCount(edges)); var baseGraph = new BasicGraph<Node, IntEdge>(edges, nodeCount) { Nodes = intGraph.Nodes }; ProperLayeredGraph = new ProperLayeredGraph(baseGraph); }
static IEnumerable<IntPair> GetFlatPairs(int[] layer, int[] layering, BasicGraph<IntEdge> intGraph) { return new Set<IntPair>(from v in layer where v < intGraph.NodeCount from edge in intGraph.OutEdges(v) where layering[edge.Source] == layering[edge.Target] select new IntPair(edge.Source, edge.Target)); }
/// <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 BasicGraph<IntEdge>(from pair in horizontalConstraints.VerticalInts select new IntEdge(pair.Item1, pair.Item2)); var verticalComponents = ConnectedComponentCalculator<IntEdge>.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; }
/// <summary> /// Creating a DAG which glues same layer vertices into one original, /// replacing original multiple edges with a single edge. /// upDown constraints will be added as edges /// </summary> void CreateGluedDagSkeletonForLayering() { GluedDagSkeletonForLayering = new BasicGraph<Node, IntEdge>(GluedDagSkeletonEdges(), originalGraph.Nodes.Count); SetGluedEdgesWeights(); }
internal LongestPathLayering(BasicGraph<IntEdge> graph){ this.graph=graph; }
private IEnumerable<IEdge> GetFeedbackSet() { this.gluedIntGraph = CreateGluedGraph(); return UnglueIntPairs(CycleRemoval<IntPair>.GetFeedbackSetWithConstraints(gluedIntGraph, this.GluedUpDownIntConstraints));//avoiding lazy evaluation }
///// <summary> ///// Computes distances between a selected set of nodes and all nodes. ///// Pivot nodes are selected with maxmin strategy (first at random, later ///// ones to maximize distances to all previously selected ones). ///// </summary> ///// <param name="graph">A graph.</param> ///// <param name="directed">Whether shortest paths are directed.</param> ///// <param name="numberOfPivots">Number of pivots.</param> ///// <returns>A square matrix with shortest path distances.</returns> //public static double[][] PivotUniformDistances(GeometryGraph graph, bool directed, int numberOfPivots) { // double[][] d = new double[numberOfPivots][]; // Node[] nodes = new Node[graph.Nodes.Count]; // graph.Nodes.CopyTo(nodes, 0); // double[] min = new double[graph.Nodes.Count]; // for (int i = 0; i < min.Length; i++) { // min[i] = Double.PositiveInfinity; // } // System.Console.Write("pivoting "); // Node pivot = nodes[0]; // for (int i = 0; i < numberOfPivots; i++) { // System.Console.Write("."); // d[i] = SingleSourceUniformDistances(graph, pivot, directed); // int argmax = 0; // for (int j = 0; j < d[i].Length; j++) { // min[j] = Math.Min(min[j], d[i][j]); // if (min[j] > min[argmax]) // argmax = j; // } // pivot = nodes[argmax]; // } // System.Console.WriteLine(); // return d; //} ///// <summary> ///// Determines whether the graph is (weakly) connected, that is, ///// if there is a path connecting every two nodes. ///// </summary> ///// <param name="graph">A graph.</param> ///// <returns>true iff the graph is connected.</returns> //public static bool IsConnected(GeometryGraph graph) { // IEnumerator<Node> enumerator = graph.Nodes.GetEnumerator(); // enumerator.MoveNext(); // Node node=enumerator.Current; // double[] distances=SingleSourceUniformDistances(graph, node, false); // for (int i = 0; i < distances.Length; i++) { // if (distances[i] == Double.PositiveInfinity) return false; // } // return true; //} /// <summary> /// Gives graphs representing the connected components of the graph /// </summary> /// <param name="graph">A graph.</param> /// <param name="nodeToNodeIndex">the dictionary: node -> node index in the NodeMap</param> /// <returns>An array of connected components.</returns> internal static GeometryGraph[] ComponentGraphs(GeometryGraph graph, Dictionary<Node, int> nodeToNodeIndex) { Node[] nodes = new Node[graph.Nodes.Count]; graph.Nodes.CopyTo(nodes, 0); BasicGraph<IntPair> basicGraph = new BasicGraph<IntPair>( from edge in graph.Edges where ! (edge.Source is Cluster || edge.Target is Cluster) select new IntPair(nodeToNodeIndex[edge.Source], nodeToNodeIndex[edge.Target]), graph.Nodes.Count); List<IEnumerable<int>> comps = new List<IEnumerable<int>>( ConnectedComponentCalculator<IntPair>.GetComponents(basicGraph)); if (comps.Count == 1) return new GeometryGraph[] { graph }; GeometryGraph[] ret = new GeometryGraph[comps.Count]; int i = 0; foreach (var comp in comps) ret[i++] = GeomGraphFromBasicGraph(comp, nodes); return ret; }