/// <summary> /// Uses GraphSharp CompoundFDPLayoutAlgorithm, i.e. a force-based algorithm. /// /// Pretty effective - for not too complicated graphs it is capable of providing flawless solution. /// </summary> /// <returns>raw set of coordinates of vertices</returns> private IDictionary <string, Point> Create4() { var algo4 = new CompoundFDPLayoutAlgorithm <string, Edge <string>, BidirectionalGraph <string, Edge <string> > >( graph, vertexSizes, vertexBorders, new Dictionary <string, CompoundVertexInnerLayoutType>()); algo4.Compute(); //while (algo4.State != ComputationState.Finished) // Thread.Sleep(250); return(algo4.VertexPositions); }
/// <summary> /// Performs the actual layout algorithm. /// </summary> /// <param name="graph">The object containing the graph data</param> /// <param name="rootNode">Root node</param> protected override void PerformLayout(GraphMapData graph, INode rootNode) { BidirectionalGraph<string, WeightedEdge<string>> bGraph = GraphSharpUtility.GetBidirectionalGraph(graph); IDictionary<string, Size> nodeSizes = GraphSharpUtility.GetNodeSizes(graph); IDictionary<string, Vector> nodePositions = GraphSharpUtility.GetNodePositions(graph); CompoundFDPLayoutParameters compoundFDPLayoutParameters = new CompoundFDPLayoutParameters(); CompoundFDPLayoutAlgorithm<string, WeightedEdge<string>, BidirectionalGraph<string, WeightedEdge<string>>> compoundFDPLayoutAlgorithm = new CompoundFDPLayoutAlgorithm<string, WeightedEdge<string>, BidirectionalGraph<string, WeightedEdge<string>>>(bGraph, nodeSizes, null, null, nodePositions, compoundFDPLayoutParameters); compoundFDPLayoutAlgorithm.Compute(); GraphSharpUtility.SetNodePositions(graph, compoundFDPLayoutAlgorithm.VertexPositions); }
/// <summary> /// Performs the actual layout algorithm. /// </summary> /// <param name="graph">The object containing the graph data</param> /// <param name="rootNode">Root node</param> protected override void PerformLayout(GraphMapData graph, INode rootNode) { BidirectionalGraph <string, WeightedEdge <string> > bGraph = GraphSharpUtility.GetBidirectionalGraph(graph); IDictionary <string, Size> nodeSizes = GraphSharpUtility.GetNodeSizes(graph); IDictionary <string, Vector> nodePositions = GraphSharpUtility.GetNodePositions(graph); CompoundFDPLayoutParameters compoundFDPLayoutParameters = new CompoundFDPLayoutParameters(); CompoundFDPLayoutAlgorithm <string, WeightedEdge <string>, BidirectionalGraph <string, WeightedEdge <string> > > compoundFDPLayoutAlgorithm = new CompoundFDPLayoutAlgorithm <string, WeightedEdge <string>, BidirectionalGraph <string, WeightedEdge <string> > >(bGraph, nodeSizes, null, null, nodePositions, compoundFDPLayoutParameters); compoundFDPLayoutAlgorithm.Compute(); GraphSharpUtility.SetNodePositions(graph, compoundFDPLayoutAlgorithm.VertexPositions); }
private double EvaluateFitnessForGraph(CompoundFDPLayoutParameters chromosome, CompoundGraph <object, IEdge <object> > compoundGraph) { var sizes = new Dictionary <object, Size>(); var borders = new Dictionary <object, Thickness>(); var layoutType = new Dictionary <object, CompoundVertexInnerLayoutType>(); var s = new Size(20, 20); foreach (var v in compoundGraph.SimpleVertices) { sizes[v] = s; } var b = new Thickness(5, 10, 5, 5); foreach (var v in compoundGraph.CompoundVertices) { sizes[v] = new Size(); borders[v] = b; layoutType[v] = CompoundVertexInnerLayoutType.Automatic; } //run the compound FDP algorithm var algorithm = new CompoundFDPLayoutAlgorithm <object, IEdge <object>, CompoundGraph <object, IEdge <object> > >( compoundGraph, sizes, borders, layoutType, null, chromosome); algorithm.Compute(); double fitness = 0.0; //refresh the sizes of the compound vertices foreach (var v in compoundGraph.CompoundVertices) { var border = borders[v]; var innerCanvasSize = algorithm.InnerCanvasSizes[v]; var size = new Size( border.Left + innerCanvasSize.Width + border.Right, border.Top + innerCanvasSize.Height + border.Bottom ); sizes[v] = size; } //NODE OVERLAP double overlaps = EvaluateNodeOverlaps(compoundGraph, algorithm, sizes); /*if (overlaps > 0.0) * return double.NaN;*/ fitness += overlaps * NODE_OVERLAP_MULTIPLIER; //CANVAS SIZE Size canvasSize = EvaluateCanvasSize(compoundGraph, algorithm, sizes); fitness += canvasSize.Width * canvasSize.Height * CANVAS_SIZE_MULTIPLIER; //CANVAS RATIO double canvasRatio = canvasSize.Width / canvasSize.Height; canvasRatio = canvasRatio < 1 ? 1 / canvasRatio : canvasRatio; fitness += canvasRatio * CANVAS_RATIO_MULTIPLIER; //NODE DISTANCES double minimalMinDistance, averageMinDistance, maximalMinDistance; double idealDistance = chromosome.IdealEdgeLength; EvaluateNodeDistances(compoundGraph, algorithm, sizes, out minimalMinDistance, out averageMinDistance, out maximalMinDistance); fitness += (averageMinDistance - idealDistance) * NODE_DISTANCE_MULTIPLIER; fitness += (minimalMinDistance - idealDistance) * NODE_DISTANCE_MULTIPLIER; fitness += (maximalMinDistance - idealDistance) * NODE_DISTANCE_MULTIPLIER; //EDGE LENGTH double edgeLength = EvaluateEdgeLength(compoundGraph, algorithm, sizes, chromosome.IdealEdgeLength, chromosome.NestingFactor); fitness += edgeLength * EDGE_LENGTH_MULTIPLIER; //EDGE CROSSING double edgeCrossing = EvaluateEdgeCrossing(compoundGraph, algorithm, sizes); fitness += edgeCrossing * EDGE_CROSSING_MULTIPLIER; //PHASE_LENGTH double phaseLength = (chromosome.Phase1Iterations + chromosome.Phase2Iterations + chromosome.Phase3Iterations) * PHASE_LENGTH_MULTIPLIER; fitness += phaseLength; return(fitness); }
private void ShowGraph(int graphIndex) { CompoundGraph <object, IEdge <object> > graph = _graphs[graphIndex]; _rectangles.Clear(); _lines.Clear(); Layout.Children.Clear(); var origo = new Ellipse { Width = 100, Height = 100, Fill = System.Windows.Media.Brushes.Black, OpacityMask = new RadialGradientBrush(Colors.Black, Colors.Transparent) }; Canvas.SetLeft(origo, -5); Canvas.SetTop(origo, -5); Layout.Children.Add(origo); var sizes = new Dictionary <object, Size>(); var borders = new Dictionary <object, Thickness>(); var layoutType = new Dictionary <object, CompoundVertexInnerLayoutType>(); var size = new Size(20, 20); foreach (object vertex in graph.SimpleVertices) { sizes[vertex] = size; } var thickness = new Thickness(5, 10, 5, 5); foreach (object vertex in graph.CompoundVertices) { sizes[vertex] = default; borders[vertex] = thickness; layoutType[vertex] = CompoundVertexInnerLayoutType.Automatic; } var worker = new BackgroundWorker { WorkerReportsProgress = true }; worker.DoWork += (sender, args) => { var layoutAlgorithm = new CompoundFDPLayoutAlgorithm <object, IEdge <object>, ICompoundGraph <object, IEdge <object> > >( graph, sizes, borders, layoutType, _parameters); layoutAlgorithm.IterationEnded += (s, iterationArgs) => { var testIterationArgs = iterationArgs as TestingCompoundLayoutIterationEventArgs <object, IEdge <object>, TestingCompoundVertexInfo, object>; IDictionary <object, Point> positions = testIterationArgs?.VerticesPositions; if (positions is null) { return; } IDictionary <object, Size> innerSizes = ((ICompoundLayoutIterationEventArgs <object>)testIterationArgs).InnerCanvasSizes; IDictionary <object, TestingCompoundVertexInfo> verticesInfos = testIterationArgs.VerticesInfos; Dispatcher.Invoke(() => { var points = new Dictionary <object, Point>(); var compoundVerticesToCheck = new Queue <object>(); var compoundVertices = new List <object>(); var roots = graph.CompoundVertices.Where(vertex => graph.GetParent(vertex) is null); foreach (object root in roots) { compoundVerticesToCheck.Enqueue(root); } while (compoundVerticesToCheck.Count > 0) { object next = compoundVerticesToCheck.Dequeue(); if (!graph.IsCompoundVertex(next)) { continue; } compoundVertices.Add(next); foreach (object childrenVertex in graph.GetChildrenVertices(next)) { compoundVerticesToCheck.Enqueue(childrenVertex); } } // Draw the compound vertices foreach (object vertex in compoundVertices) { Size innerSize = innerSizes[vertex]; innerSize.Width += thickness.Left + thickness.Right; innerSize.Height += thickness.Top + thickness.Bottom; Point pos = positions[vertex]; points[vertex] = pos; AddRectangle(vertex, pos, innerSize); } // Draw the simple vertices foreach (object vertex in graph.SimpleVertices) { Point pos = positions[vertex]; points[vertex] = pos; AddRectangle(vertex, pos, size); } // Draw the simple edges foreach (IEdge <object> edge in graph.Edges) { Point pos1 = points[edge.Source]; Point pos2 = points[edge.Target]; AddLine(edge, pos1, pos2, true); } // Draw the containment edges foreach (object vertex in graph.CompoundVertices) { Point pos1 = points[vertex]; foreach (object child in graph.GetChildrenVertices(vertex)) { Point pos2 = points[child]; AddLine(child, pos1, pos2, false); } } // Draw the lines of the forces foreach (Line forceLine in _forceLines) { Layout.Children.Remove(forceLine); } SolidColorBrush springColor = System.Windows.Media.Brushes.Orange; SolidColorBrush repulsionColor = System.Windows.Media.Brushes.Red; SolidColorBrush gravityColor = System.Windows.Media.Brushes.Green; SolidColorBrush applicationColor = System.Windows.Media.Brushes.Yellow; foreach (KeyValuePair <object, TestingCompoundVertexInfo> pair in verticesInfos) { Line line = CreateLine(points[pair.Key], pair.Value.SpringForce, springColor); Layout.Children.Add(line); _forceLines.Add(line); line = CreateLine(points[pair.Key], pair.Value.RepulsionForce, repulsionColor); Layout.Children.Add(line); _forceLines.Add(line); line = CreateLine(points[pair.Key], pair.Value.GravityForce, gravityColor); Layout.Children.Add(line); _forceLines.Add(line); line = CreateLine(points[pair.Key], pair.Value.ApplicationForce, applicationColor); Layout.Children.Add(line); _forceLines.Add(line); } // Set the position of the gravity center Animate( origo, Canvas.LeftProperty, testIterationArgs.GravitationCenter.X - origo.Width / 2.0, _animationDuration); Animate( origo, Canvas.TopProperty, testIterationArgs.GravitationCenter.Y - origo.Height / 2.0, _animationDuration); TxtMessage.Text = testIterationArgs.Message; }); do { Thread.Sleep((int)_animationDuration.TimeSpan.TotalMilliseconds); } while (_paused); }; layoutAlgorithm.Compute(); }; worker.RunWorkerAsync(); }
private void ShowGraph(int graphIndex) { CompoundGraph <object, IEdge <object> > g = graphs[graphIndex]; _rectDict.Clear(); _lineDict.Clear(); lc.Children.Clear(); var origo = new Ellipse(); origo.Width = 100; origo.Height = 100; origo.Fill = Brushes.Black; origo.OpacityMask = new RadialGradientBrush(Colors.Black, Colors.Transparent); Canvas.SetLeft(origo, -5); Canvas.SetTop(origo, -5); lc.Children.Add(origo); var sizes = new Dictionary <object, Size>(); var borders = new Dictionary <object, Thickness>(); var layoutType = new Dictionary <object, CompoundVertexInnerLayoutType>(); var s = new Size(20, 20); foreach (var v in g.SimpleVertices) { sizes[v] = s; } var b = new Thickness(5, 10, 5, 5); foreach (var v in g.CompoundVertices) { sizes[v] = new Size(); borders[v] = b; layoutType[v] = CompoundVertexInnerLayoutType.Automatic; } var worker = new BackgroundWorker(); worker.WorkerReportsProgress = true; worker.DoWork += (sender, e) => { var layoutAlgorithm = new CompoundFDPLayoutAlgorithm <object, IEdge <object>, ICompoundGraph <object, IEdge <object> > >( g, sizes, borders, layoutType, null, parameters); layoutAlgorithm.IterationEnded += (o, evt) => { var args = evt as TestingCompoundLayoutIterationEventArgs <object, IEdge <object>, TestingCompoundVertexInfo, object>; var positions = args.VertexPositions; var innerSizes = (args as ICompoundLayoutIterationEventArgs <object>).InnerCanvasSizes; var vertexInfos = args.VertexInfos; Dispatcher.Invoke(new Action(delegate { var pDict = new Dictionary <object, Point>(); var compoundVerticesToCheck = new Queue <object>(); var compoundVertices = new List <object>(); var root = g.CompoundVertices.Where( cv => g.GetParent(cv) == null); foreach (var r in root) { compoundVerticesToCheck.Enqueue(r); } while (compoundVerticesToCheck.Count > 0) { var next = compoundVerticesToCheck.Dequeue(); if (!g.IsCompoundVertex(next)) { continue; } compoundVertices.Add(next); foreach ( var childrenVertex in g.GetChildrenVertices(next)) { compoundVerticesToCheck.Enqueue( childrenVertex); } } //draw the compound vertices foreach (var v in compoundVertices) { var size = innerSizes[v]; size.Width += b.Left + b.Right; size.Height += b.Top + b.Bottom; var pos = positions[v]; pDict[v] = pos; AddRect(v, pos, size); } //draw the simple vertices foreach (var v in g.SimpleVertices) { var pos = positions[v]; pDict[v] = pos; AddRect(v, pos, s); } //draw the simple edges foreach (var edge in g.Edges) { var pos1 = pDict[edge.Source]; var pos2 = pDict[edge.Target]; AddLine(edge, pos1, pos2, true); } //draw the containment edges /*foreach (var v in g.CompoundVertices) * { * var pos1 = pDict[v]; * foreach (var c in g.GetChildrenVertices(v)) * { * var pos2 = pDict[c]; * AddLine(c, pos1, pos2, false); * } * }*/ //draw the lines of the forces foreach (var forceLine in _forceLines) { lc.Children.Remove(forceLine); } var springColor = Brushes.Orange; var repulsionColor = Brushes.Red; var gravityColor = Brushes.Green; var applicationColor = Brushes.Yellow; foreach (var kvp in vertexInfos) { var line = CreateLine(pDict[kvp.Key], kvp.Value.SpringForce, springColor); lc.Children.Add(line); _forceLines.Add(line); line = CreateLine(pDict[kvp.Key], kvp.Value.RepulsionForce, repulsionColor); lc.Children.Add(line); _forceLines.Add(line); line = CreateLine(pDict[kvp.Key], kvp.Value.GravityForce, gravityColor); lc.Children.Add(line); _forceLines.Add(line); line = CreateLine(pDict[kvp.Key], kvp.Value.ApplicationForce, applicationColor); lc.Children.Add(line); _forceLines.Add(line); } //set the position of the gravity center Animate(origo, Canvas.LeftProperty, args.GravitationCenter.X - origo.Width / 2.0, animationDuration); Animate(origo, Canvas.TopProperty, args.GravitationCenter.Y - origo.Height / 2.0, animationDuration); txtMessage.Text = args.Message; })); do { Thread.Sleep((int)animationDuration.TimeSpan.TotalMilliseconds); } while (_paused); }; layoutAlgorithm.Compute(); }; worker.RunWorkerAsync(); }
private void ShowGraph(int graphIndex) { CompoundGraph<object, IEdge<object>> g = graphs[graphIndex]; _rectDict.Clear(); _lineDict.Clear(); lc.Children.Clear(); var origo = new Ellipse(); origo.Width = 100; origo.Height = 100; origo.Fill = Brushes.Black; origo.OpacityMask = new RadialGradientBrush(Colors.Black, Colors.Transparent); Canvas.SetLeft(origo, -5); Canvas.SetTop(origo, -5); lc.Children.Add(origo); var sizes = new Dictionary<object, Size>(); var borders = new Dictionary<object, Thickness>(); var layoutType = new Dictionary<object, CompoundVertexInnerLayoutType>(); var s = new Size(20, 20); foreach (var v in g.SimpleVertices) { sizes[v] = s; } var b = new Thickness(5, 10, 5, 5); foreach (var v in g.CompoundVertices) { sizes[v] = new Size(); borders[v] = b; layoutType[v] = CompoundVertexInnerLayoutType.Automatic; } var worker = new BackgroundWorker(); worker.WorkerReportsProgress = true; worker.DoWork += (sender, e) => { var layoutAlgorithm = new CompoundFDPLayoutAlgorithm <object, IEdge<object>, ICompoundGraph<object, IEdge<object>>>( g, sizes, borders, layoutType, null, parameters); layoutAlgorithm.IterationEnded += (o, evt) => { var args = evt as TestingCompoundLayoutIterationEventArgs<object, IEdge<object>, TestingCompoundVertexInfo, object>; var positions = args.VertexPositions; var innerSizes = (args as ICompoundLayoutIterationEventArgs<object>).InnerCanvasSizes; var vertexInfos = args.VertexInfos; Dispatcher.Invoke(new Action(delegate { var pDict = new Dictionary<object, Point>(); var compoundVerticesToCheck = new Queue<object>(); var compoundVertices = new List<object>(); var root = g.CompoundVertices.Where( cv => g.GetParent(cv) == null); foreach (var r in root) compoundVerticesToCheck.Enqueue(r); while (compoundVerticesToCheck.Count > 0) { var next = compoundVerticesToCheck.Dequeue(); if (!g.IsCompoundVertex(next)) continue; compoundVertices.Add(next); foreach ( var childrenVertex in g.GetChildrenVertices(next)) { compoundVerticesToCheck.Enqueue( childrenVertex); } } //draw the compound vertices foreach (var v in compoundVertices) { var size = innerSizes[v]; size.Width += b.Left + b.Right; size.Height += b.Top + b.Bottom; var pos = positions[v]; pDict[v] = pos; AddRect(v, pos, size); } //draw the simple vertices foreach (var v in g.SimpleVertices) { var pos = positions[v]; pDict[v] = pos; AddRect(v, pos, s); } //draw the simple edges foreach (var edge in g.Edges) { var pos1 = pDict[edge.Source]; var pos2 = pDict[edge.Target]; AddLine(edge, pos1, pos2, true); } //draw the containment edges /*foreach (var v in g.CompoundVertices) { var pos1 = pDict[v]; foreach (var c in g.GetChildrenVertices(v)) { var pos2 = pDict[c]; AddLine(c, pos1, pos2, false); } }*/ //draw the lines of the forces foreach (var forceLine in _forceLines) lc.Children.Remove(forceLine); var springColor = Brushes.Orange; var repulsionColor = Brushes.Red; var gravityColor = Brushes.Green; var applicationColor = Brushes.Yellow; foreach (var kvp in vertexInfos) { var line = CreateLine(pDict[kvp.Key], kvp.Value.SpringForce, springColor); lc.Children.Add(line); _forceLines.Add(line); line = CreateLine(pDict[kvp.Key], kvp.Value.RepulsionForce, repulsionColor); lc.Children.Add(line); _forceLines.Add(line); line = CreateLine(pDict[kvp.Key], kvp.Value.GravityForce, gravityColor); lc.Children.Add(line); _forceLines.Add(line); line = CreateLine(pDict[kvp.Key], kvp.Value.ApplicationForce, applicationColor); lc.Children.Add(line); _forceLines.Add(line); } //set the position of the gravity center Animate(origo, Canvas.LeftProperty, args.GravitationCenter.X - origo.Width / 2.0, animationDuration); Animate(origo, Canvas.TopProperty, args.GravitationCenter.Y - origo.Height / 2.0, animationDuration); txtMessage.Text = args.Message; })); do { Thread.Sleep((int) animationDuration.TimeSpan.TotalMilliseconds); } while (_paused); }; layoutAlgorithm.Compute(); }; worker.RunWorkerAsync(); }
public void Evaluate(int SpreadMax) { if (FBuild[0] || (pd.InputChanged && init)) { graph.Clear(); VSize.Clear(); VThickness.Clear(); VType.Clear(); VPos.Clear(); VCache.Clear(); for (int i = 0; i < FVertices.SliceCount; i++) { graph.AddVertex(FVertices[i]); VSize.Add(FVertices[i], new Size(FVSize[i], FVSize[i])); VThickness.Add(FVertices[i], new Thickness(1.0)); VType.Add(FVertices[i], FVType[i]); VPos.Add(FVertices[i], new Point(FVPos[i].x, FVPos[i].y)); VCache.Add(FVertices[i]); } for (int i = 0; i < Math.Max(FEdgeFrom.SliceCount, FEdgeTo.SliceCount); i++) { graph.AddEdge(new Edge <string>(FEdgeFrom[i], FEdgeTo[i])); } var cparams = new CompoundFDPLayoutParameters(); foreach (var prop in typeof(CompoundFDPLayoutParameters).GetProperties()) { var input = pd.InputPins[prop.Name].Spread[0]; if (!(input.ToString().StartsWith("0") && input.ToString().EndsWith("0"))) { prop.SetValue(cparams, pd.InputPins[prop.Name].Spread[0]); } } layout = new CompoundFDPLayoutAlgorithm <string, IEdge <string>, CompoundGraph <string, IEdge <string> > >(graph, VSize, VThickness, VType, VPos, cparams); foreach (var prop in typeof(CompoundFDPLayoutParameters).GetProperties()) { var input = pd.InputPins[prop.Name].Spread[0]; if (!(input.ToString().StartsWith("0") && input.ToString().EndsWith("0"))) { prop.SetValue(layout.Parameters, pd.InputPins[prop.Name].Spread[0]); } } layout.Finished += (sender, args) => { FPosOut.SliceCount = VCache.Count; for (int i = 0; i < VCache.Count; i++) { var point = layout.VertexPositions[VCache[i]]; FPosOut[i] = new Vector2D(point.X, point.Y); } }; if (FAsync[0]) { Task.Run(() => { layout.Compute(); }); } else { layout.Compute(); } init = true; } if (layout != null) { FState[0] = layout.State.ToString(); } }
private static double EvaluateFitnessForGraph( [NotNull] CompoundFDPLayoutParameters chromosome, [NotNull] CompoundGraph <object, IEdge <object> > compoundGraph) { var verticesSizes = new Dictionary <object, Size>(); var verticesBorders = new Dictionary <object, Thickness>(); var layoutTypes = new Dictionary <object, CompoundVertexInnerLayoutType>(); var size = new Size(20, 20); foreach (object v in compoundGraph.SimpleVertices) { verticesSizes[v] = size; } var border = new Thickness(5, 10, 5, 5); foreach (object v in compoundGraph.CompoundVertices) { verticesSizes[v] = new Size(); verticesBorders[v] = border; layoutTypes[v] = CompoundVertexInnerLayoutType.Automatic; } // Run the compound FDP algorithm var algorithm = new CompoundFDPLayoutAlgorithm <object, IEdge <object>, CompoundGraph <object, IEdge <object> > >( compoundGraph, verticesSizes, verticesBorders, layoutTypes, chromosome); algorithm.Compute(); double fitness = 0.0; // Refresh the sizes of the compound vertices foreach (object v in compoundGraph.CompoundVertices) { Thickness b = verticesBorders[v]; Size innerCanvasSize = algorithm.InnerCanvasSizes[v]; var s = new Size( b.Left + innerCanvasSize.Width + b.Right, b.Top + innerCanvasSize.Height + b.Bottom); verticesSizes[v] = s; } // NODE OVERLAP double overlaps = EvaluateNodeOverlaps(compoundGraph, algorithm, verticesSizes); fitness += overlaps * NodeOverlapMultiplier; // CANVAS SIZE Size canvasSize = EvaluateCanvasSize(compoundGraph, algorithm, verticesSizes); fitness += canvasSize.Width * canvasSize.Height * CanvasSizeMultiplier; // CANVAS RATIO double canvasRatio = canvasSize.Width / canvasSize.Height; canvasRatio = canvasRatio < 1 ? 1 / canvasRatio : canvasRatio; fitness += canvasRatio * CanvasRatioMultiplier; // NODE DISTANCES double idealDistance = chromosome.IdealEdgeLength; EvaluateNodeDistances( compoundGraph, algorithm, verticesSizes, out double minimalMinDistance, out double averageMinDistance, out double maximalMinDistance); fitness += (averageMinDistance - idealDistance) * NodeDistanceMultiplier; fitness += (minimalMinDistance - idealDistance) * NodeDistanceMultiplier; fitness += (maximalMinDistance - idealDistance) * NodeDistanceMultiplier; // EDGE LENGTH double edgeLength = EvaluateEdgeLength( compoundGraph, algorithm, verticesSizes, chromosome.IdealEdgeLength, chromosome.NestingFactor); fitness += edgeLength * EdgeLengthMultiplier; // EDGE CROSSING double edgeCrossing = EvaluateEdgeCrossing(compoundGraph, algorithm, verticesSizes); fitness += edgeCrossing * EdgeCrossingMultiplier; // PHASE_LENGTH double phaseLength = chromosome.Phase1Iterations + chromosome.Phase2Iterations + chromosome.Phase3Iterations; phaseLength *= PhaseLengthMultiplier; fitness += phaseLength; return(fitness); }