コード例 #1
0
        /// <summary>
        /// Computes the "stress" of the current layout of the given graph:
        ///
        ///   stress = sum_{(u,v) in V} D(u,v)^(-2) (d(u,v) - D(u,v))^2
        ///
        /// where:
        ///   V is the set of nodes
        ///   d(u,v) is the euclidean distance between the centers of nodes u and v
        ///   D(u,v) is the graph-theoretic path length between u and v - scaled by average edge length.
        ///
        /// The idea of “stress” in graph layout is that nodes that are immediate neighbors should be closer
        /// together than nodes that are a few hops apart (i.e. that have path length>1).  More generally
        /// the distance between nodes in the drawing should be proportional to the path length between them.
        /// The lower the “stress” score of a particular graph layout the better it conforms to this ideal.
        ///
        /// </summary>
        /// <param name="graph"></param>
        /// <returns></returns>
        public static double Stress(GeometryGraph graph)
        {
            ValidateArg.IsNotNull(graph, "graph");
            double stress = 0;

            if (graph.Edges.Count == 0)
            {
                return(stress);
            }
            var apd = new AllPairsDistances(graph);

            apd.Run();
            var    D = apd.Result;
            double l = graph.Edges.Average(e => e.Length);
            int    i = 0;

            foreach (var u in graph.Nodes)
            {
                int j = 0;
                foreach (var v in graph.Nodes)
                {
                    if (i != j)
                    {
                        double duv = (u.Center - v.Center).Length;
                        double Duv = l * D[i][j];
                        double d   = Duv - duv;
                        stress += d * d / (Duv * Duv);
                    }
                    ++j;
                }
                ++i;
            }
            return(stress);
        }
コード例 #2
0
        /// <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);
            }
        }
コード例 #3
0
 /// <summary>
 /// Computes the "stress" of the current layout of the given graph:
 /// 
 ///   stress = sum_{(u,v) in V} D(u,v)^(-2) (d(u,v) - D(u,v))^2
 /// 
 /// where:
 ///   V is the set of nodes
 ///   d(u,v) is the euclidean distance between the centers of nodes u and v
 ///   D(u,v) is the graph-theoretic path length between u and v - scaled by average edge length.
 ///   
 /// The idea of “stress” in graph layout is that nodes that are immediate neighbors should be closer 
 /// together than nodes that are a few hops apart (i.e. that have path length>1).  More generally 
 /// the distance between nodes in the drawing should be proportional to the path length between them.  
 /// The lower the “stress” score of a particular graph layout the better it conforms to this ideal.
 /// 
 /// </summary>
 /// <param name="graph"></param>
 /// <returns></returns>
 public static double Stress(GeometryGraph graph)
 {
     ValidateArg.IsNotNull(graph, "graph");
     double stress = 0;
     if (graph.Edges.Count == 0)
     {
         return stress;
     }
     var apd = new AllPairsDistances(graph, false);
     apd.Run();
     var D = apd.Result;
     double l = graph.Edges.Average(e => e.Length);
     int i = 0;
     foreach (var u in graph.Nodes)
     {
         int j = 0;
         foreach (var v in graph.Nodes)
         {
             if (i != j)
             {
                 double duv = (u.Center - v.Center).Length;
                 double Duv = l * D[i][j];
                 double d = Duv - duv;
                 stress += d * d / (Duv * Duv);
             }
             ++j;
         }
         ++i;
     }
     return stress;
 }
コード例 #4
0
        /// <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);
            }
        }