/// <summary> /// Layouts a connected graph with Multidimensional Scaling, using /// shortest-path distances as Euclidean target distances. /// </summary> /// <param name="geometryGraph">A graph.</param> /// <param name="settings">The settings for the algorithm.</param> /// <param name="x">Coordinate vector.</param> /// <param name="y">Coordinate vector.</param> internal static void LayoutGraphWithMds(GeometryGraph geometryGraph, MdsLayoutSettings settings, out double[] x, out double[] y) { x = new double[geometryGraph.Nodes.Count]; y = new double[geometryGraph.Nodes.Count]; if (geometryGraph.Nodes.Count == 0) { return; } if (geometryGraph.Nodes.Count == 1) { x[0] = y[0] = 0; return; } int k = Math.Min(settings.PivotNumber, geometryGraph.Nodes.Count); int iter = settings.GetNumberOfIterationsWithMajorization(geometryGraph.Nodes.Count); double exponent = settings.Exponent; var pivotArray = new int[k]; PivotDistances pivotDistances = new PivotDistances(geometryGraph, false, pivotArray); pivotDistances.Run(); double[][] c = pivotDistances.Result; MultidimensionalScaling.LandmarkClassicalScaling(c, out x, out y, pivotArray); ScaleToAverageEdgeLength(geometryGraph, x, y); if (iter > 0) { AllPairsDistances apd = new AllPairsDistances(geometryGraph, false); apd.Run(); double[][] d = apd.Result; double[][] w = MultidimensionalScaling.ExponentialWeightMatrix(d, exponent); // MultidimensionalScaling.DistanceScaling(d, x, y, w, iter); MultidimensionalScaling.DistanceScalingSubset(d, x, y, w, iter); } }
void SetNodePositionsAndMovedBoundaries() { int pivotNumber = Math.Min(graph.Nodes.Count,settings.PivotNumber); double scaleX = settings.ScaleX; double scaleY = settings.ScaleY; int[] pivotArray = new int[pivotNumber]; PivotDistances pivotDistances = new PivotDistances(graph, false, pivotArray); pivotDistances.Run(); double[][] c = pivotDistances.Result; double[] x, y; MultidimensionalScaling.LandmarkClassicalScaling(c, out x, out y, pivotArray); Standardize(x); double[] p = Centrality.PageRank(graph, .85, false); // double[] q = Centrality.PageRank(graph, .85, true); Standardize(p); // Standardize(q); int index = 0; foreach (Node node in graph.Nodes) { node.Center = new Point((int) (x[index]*scaleX), (int) (Math.Sqrt(p[index])*scaleY)); index++; } OverlapRemoval.RemoveOverlaps(graph.Nodes.ToArray(), settings.NodeSeparation); }
/// <summary> /// Layouts a connected graph with Multidimensional Scaling, using /// shortest-path distances as Euclidean target distances. /// </summary> /// <param name="geometryGraph">A graph.</param> /// <param name="settings">The settings for the algorithm.</param> /// <param name="x">Coordinate vector.</param> /// <param name="y">Coordinate vector.</param> internal static void LayoutGraphWithMds(GeometryGraph geometryGraph, MdsLayoutSettings settings, out double[] x, out double[] y) { x = new double[geometryGraph.Nodes.Count]; y = new double[geometryGraph.Nodes.Count]; if (geometryGraph.Nodes.Count == 0) return; if (geometryGraph.Nodes.Count == 1) { x[0] = y[0] = 0; return; } int k = Math.Min(settings.PivotNumber, geometryGraph.Nodes.Count); int iter = settings.GetNumberOfIterationsWithMajorization(geometryGraph.Nodes.Count); double exponent = settings.Exponent; var pivotArray = new int[k]; PivotDistances pivotDistances = new PivotDistances(geometryGraph, false, pivotArray); pivotDistances.Run(); double[][] c = pivotDistances.Result; MultidimensionalScaling.LandmarkClassicalScaling(c, out x, out y, pivotArray); ScaleToAverageEdgeLength(geometryGraph, x, y); if (iter > 0) { AllPairsDistances apd = new AllPairsDistances(geometryGraph, false); apd.Run(); double[][] d = apd.Result; double[][] w = MultidimensionalScaling.ExponentialWeightMatrix(d, exponent); // MultidimensionalScaling.DistanceScaling(d, x, y, w, iter); MultidimensionalScaling.DistanceScalingSubset(d, x, y, w, iter); } }