public bool Arrange(IGraph graph, AnnealLayoutInfo info, LayoutProgress progress) { _tempGraph = new Graph(graph); _info = info; float nsize = 0; foreach (INode node in graph.Nodes) { nsize += node.Bounds.Width; } averageNodeSize = nsize / graph.Nodes.Count; // determine what the graph boundaries should be if (info.LayoutArea != RectangleF.Empty) { _drawingArea = info.LayoutArea; } else { double squareSize = averageNodeSize * Math.Ceiling(Math.Sqrt(graph.Nodes.Count)); double width = squareSize * info.WidthHeightRatio; double height = squareSize / info.WidthHeightRatio; _drawingArea = new RectangleF(0, 0, (float)width * 4.5f, (float)height * 4.5f); } // start with random positions if (info.Randomize) { Random rnd = new Random(); foreach (GraphNode node in _tempGraph.Nodes) { node.Center = new PointF( _drawingArea.Left + (float)rnd.NextDouble() * _drawingArea.Width, _drawingArea.Top + (float)rnd.NextDouble() * _drawingArea.Height); } } if (progress != null) { progress(0, _info.Stages + 2); } SetGraphElements(); SetInitStep(); CalculateInitialState(); _temperature = _info.Temperature; double totalCost = CostFunction(); double previousCost; double stopIterCond; Random rand = new Random(); // cool down for the specified number of annealing stages for (int stage = 0; stage < _info.Stages; stage++) { for (int iter = 0; iter < _info.IterationsPerStage; iter++) { previousCost = totalCost; for (int n = 0; n < _tempGraph.Nodes.Count; n++) { double oldNodeCost = evalCost(_nodes[n]); foreach (int i in Enum.GetValues(typeof(ShiftTo))) { ShiftNode(_nodes[n], (ShiftTo)i, false); if (!nodeInBounds(_nodes[n])) { ShiftNode(_nodes[n], (ShiftTo)i, true); continue; } double newNodeCost = evalCost(_nodes[n]); double newTotalCost = totalCost - oldNodeCost + newNodeCost; if (newNodeCost < oldNodeCost || Math.Pow(Math.E, (totalCost - newTotalCost) / _temperature) > rand.NextDouble()) { totalCost = newTotalCost; CommitMove(_nodes[n]); break; } else { ShiftNode(_nodes[n], (ShiftTo)i, true); RollbackMove(_nodes[n]); } } } stopIterCond = previousCost / totalCost; if (stopIterCond > .98 && stopIterCond <= 1) { break; } } SetTemperature(); DecreaseMoveValue(); if (progress != null) { progress(stage + 1, _info.Stages + 2); } } FineTuning(); if (progress != null) { progress(_info.Stages + 2, _info.Stages + 2); } foreach (GraphNode node in _tempGraph.Nodes) { node.Node.Bounds = node.Bounds; } return(true); }
public bool Arrange(IGraph graph, AnnealLayoutInfo info, LayoutProgress progress) { _tempGraph = new Graph(graph); _info = info; float nsize = 0; foreach (INode node in graph.Nodes) nsize += node.Bounds.Width; averageNodeSize = nsize / graph.Nodes.Count; // determine what the graph boundaries should be if (info.LayoutArea != RectangleF.Empty) { _drawingArea = info.LayoutArea; } else { double squareSize = averageNodeSize * Math.Ceiling(Math.Sqrt(graph.Nodes.Count)); double width = squareSize * info.WidthHeightRatio; double height = squareSize / info.WidthHeightRatio; _drawingArea = new RectangleF(0, 0, (float)width * 4.5f, (float)height * 4.5f); } // start with random positions if (info.Randomize) { Random rnd = new Random(); foreach (GraphNode node in _tempGraph.Nodes) { node.Center = new PointF( _drawingArea.Left + (float)rnd.NextDouble() * _drawingArea.Width, _drawingArea.Top + (float)rnd.NextDouble() * _drawingArea.Height); } } if (progress != null) progress(0, _info.Stages + 2); SetGraphElements(); SetInitStep(); CalculateInitialState(); _temperature = _info.Temperature; double totalCost = CostFunction(); double previousCost; double stopIterCond; Random rand = new Random(); // cool down for the specified number of annealing stages for (int stage = 0; stage < _info.Stages; stage++) { for (int iter = 0; iter < _info.IterationsPerStage; iter++) { previousCost = totalCost; for (int n = 0; n < _tempGraph.Nodes.Count; n++) { double oldNodeCost = evalCost(_nodes[n]); foreach (int i in Enum.GetValues(typeof(ShiftTo))) { ShiftNode(_nodes[n], (ShiftTo)i, false); if (!nodeInBounds(_nodes[n])) { ShiftNode(_nodes[n], (ShiftTo)i, true); continue; } double newNodeCost = evalCost(_nodes[n]); double newTotalCost = totalCost - oldNodeCost + newNodeCost; if (newNodeCost < oldNodeCost || Math.Pow(Math.E, (totalCost - newTotalCost) / _temperature) > rand.NextDouble()) { totalCost = newTotalCost; CommitMove(_nodes[n]); break; } else { ShiftNode(_nodes[n], (ShiftTo)i, true); RollbackMove(_nodes[n]); } } } stopIterCond = previousCost / totalCost; if (stopIterCond > .98 && stopIterCond <= 1) break; } SetTemperature(); DecreaseMoveValue(); if (progress != null) progress(stage + 1, _info.Stages + 2); } FineTuning(); if (progress != null) progress(_info.Stages + 2, _info.Stages + 2); foreach (GraphNode node in _tempGraph.Nodes) node.Node.Bounds = node.Bounds; return true; }
public bool Arrange(IGraph graph, AnnealLayoutInfo info) { return(Arrange(graph, info, null)); }
public bool Arrange(IGraph graph, AnnealLayoutInfo info) { return Arrange(graph, info, null); }