/// <summary> /// Create a new set of statistics based on a graph /// </summary> /// <param name="g">The graph to base the stats on</param> /// <returns>A GraphStatistics object representing the stats of the graph</returns> public static GraphStatistics From(Graph g) { float minX = g.nodes[0].position.X, minY = g.nodes[0].position.Y; float maxX = g.nodes[0].position.X, maxY = g.nodes[0].position.Y; foreach (var n in g.nodes) { if (n.position.X < minX) { minX = n.position.X; } if (n.position.X > maxX) { maxX = n.position.X; } if (n.position.Y < minY) { minY = n.position.Y; } if (n.position.Y > maxY) { maxY = n.position.Y; } } GraphStatistics stats = new GraphStatistics { Height = maxY - minY, Width = maxX - minX }; stats.GraphArea = new RectangleF(minX, minY, stats.Width, stats.Height); // Calculate stuff with edges float longest_edge = 0; float shortest_edge = 1; foreach (Edge e in g.edges) { float l = e.Length; if (l > longest_edge) { longest_edge = l; } if (l < shortest_edge) { shortest_edge = l; } stats.EdgeLenghtTotal += l; } stats.EdgeRatio = longest_edge / shortest_edge; IEnumerable <float> edge_lengths = g.edges.Select(s => s.Length); stats.EdgeMean = (float)mean(edge_lengths); stats.EdgeStdDev = (float)stddev(edge_lengths, stats.EdgeMean); return(stats); }
/// <summary> /// Calculate the required Bitmap size /// </summary> /// <param name="stats">The statistics to work with</param> /// <param name="intendedWidth">The intended height of the bitmap, in pixels</param> /// <param name="intendedHeight">The intended height of the bitmap, in pixels</param> /// <param name="boundary">The boundary around the graph on the image, so that there's a bit of clear space around the graph</param> /// <returns>A rectangle containing the bitmap size</returns> private void CalculateScale(GraphStatistics stats, int intendedWidth, int intendedHeight, int boundary) { _xMultiplier = (intendedWidth - (2 * boundary)) / stats.Width; _yMultiplier = (intendedHeight - (2 * boundary)) / stats.Height; _xOffset = -stats.GraphArea.X + ((float)boundary) / _xMultiplier; _yOffset = -stats.GraphArea.Y + ((float)boundary) / _yMultiplier; }
private static results runner(Graph g, string outputFile, Algorithm a) { Visualizer v = new Visualizer(); int i = 0; a.start(g); var start = Process.GetCurrentProcess().TotalProcessorTime; var stopwatch = Stopwatch.StartNew(); while (!a.step(g)) { i++; if (outputFile != null) { string s = String.Format("{0}.{1}", outputFile, i); v.Visualize(g, s); } } stopwatch.Stop(); var stop = Process.GetCurrentProcess().TotalProcessorTime; if (outputFile != null) { v.Visualize(g, outputFile, 1024, 1024); } results r = new results(); r.iterations = i + 1; r.runtime = stopwatch.ElapsedMilliseconds;//(stop - start).TotalMilliseconds; r.stats = GraphStatistics.From(g); r.graph = g; return(r); }
/// <summary> /// Start visualizing /// </summary> /// <param name="g">The graph to Visualize</param> /// <param name="path">The path to write an image to</param> /// <param name="imageWidth">The width of the image file</param> /// <param name="imageHeight">The height of the image file</param> /// <param name="boundary">The boundary around the graph on the image, so that there's a bit of clear space around the graph</param> /// <param name="nodeSize">The diameter of the nodes, in pixels</param> public void Visualize(Graph g, string path, int imageWidth = 300, int imageHeight = 300, int boundary = 30, int nodeSize = 5) { _stats = GraphStatistics.From(g); CalculateScale(_stats, imageWidth, imageHeight, boundary); _bitmap = new Bitmap(imageWidth, imageHeight); _graphics = Graphics.FromImage(_bitmap); _graphics.FillRectangle(_backgroundColor, 0, 0, _bitmap.Width, _bitmap.Height); NodeSize = nodeSize; DrawGraph(g, path); _graphics.Dispose(); _bitmap.Dispose(); }