Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
07/05/12 16:01:37 (12 years ago)
Author:
bburlacu
Message:

#1772: Refactored code in the GenealogyGraphChart and the SymbolicExpressionTreeGenealogyAnalyzer. Used gradient from HeuristicLab.Common to color the graph nodes.

Location:
branches/HeuristicLab.EvolutionaryTracking
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking.Views/3.4/GenealogyGraphChart.cs

    r8213 r8236  
    6767      if (_graph == null) return;
    6868      Chart.UpdateEnabled = false;
    69       var layers = Graph.Values.GroupBy(node => node.Rank).OrderBy(g => g.Key);
    70       // show elites in every graph level
    71       List<GenealogyGraphNode> currLayer = null, prevLayer = null;
    72       double currRank = 0.0;
    73       int count = layers.Count();
    74       for (int i = 0; i != count; ++i) {
    75         // propagate elites from successive layers
    76         bool f = currRank % 1 == 0;
    77         if (f) // if the rank is an integer, then we need to propagate elites
    78           prevLayer = currLayer;
    79         currRank = layers.ElementAt(i).Key;
    80         currLayer = layers.ElementAt(i).ToList();
    81         if (i > 0 && f) {
    82           // this following code injects elites that propagate from the previous generation into the current graph layer,
    83           // so that they can be represented as visual nodes
    84           int prevEliteCount = prevLayer.Count(node => node.IsElite);
    85           int currEliteCount = currLayer.Count(node => node.IsElite);
    86           for (int j = currEliteCount; j < prevEliteCount; ++j)
    87             currLayer.Add(prevLayer.ElementAt(j));
    88         }
    89         currLayer.Sort(); // uses the CompareTo() method inside the GenealogyGraphNode class
    90         foreach (var node in currLayer) {
     69
     70      var genealogyGraphNodes = Graph.Values.ToList();
     71      var layers = genealogyGraphNodes.GroupBy(n => n.Rank).OrderBy(g => g.Key).Select(g => Tuple.Create(g.Key, g.ToList())).ToList();
     72      List<GenealogyGraphNode> currentLayer = null;
     73      List<GenealogyGraphNode> previousLayer = null;
     74
     75      for (int i = 0; i != layers.Count(); ++i) {
     76        var layer = layers[i];
     77        double currentRank = layer.Item1;
     78        if (i > 0 && currentRank % 1 == 0) {
     79          previousLayer = currentLayer;
     80          currentLayer = layer.Item2;
     81          int d = previousLayer.Count - currentLayer.Count;
     82          if (d > 0)
     83            currentLayer.AddRange(previousLayer.Take(d));
     84        } else {
     85          currentLayer = layer.Item2;
     86        }
     87        currentLayer.Sort(); // sort descending by quality (using comparison defined in GenealogyGraphNode class)
     88
     89        x = 0; // reset horizontal coordinate
     90        // start laying out visual nodes
     91        foreach (var node in currentLayer) {
    9192          var pen = new Pen(Color.LightGray);
    9293          var nl = Environment.NewLine;
     
    102103            _visualNodeMap[node] = new List<VisualGenealogyGraphNode>();
    103104          _visualNodeMap[node].Add(visualNode);
    104           // connect visual nodes that actually represent the same individual
    105           // in the genealogy graph (this applies for elites) with a dashed line
    106           if (_visualNodeMap[node].Count > 1) {
    107             for (int c = _visualNodeMap[node].Count; c >= 2; --c) {
    108               var n1 = _visualNodeMap[node][c - 1];
    109               var n2 = _visualNodeMap[node][c - 2];
    110               var visualArc = AddArc(Chart, n1, n2, new Pen(Color.LightGray) { DashStyle = DashStyle.Dash });
    111               _visualArcMap[Tuple.Create(n1, n2)] = visualArc;
    112             }
    113           }
     105
    114106          x += Cx; // increment horizontal coordinate
    115           if (node.InEdges == null && _visualNodeMap.ContainsKey(node)) continue;
    116           // add visual edges
    117           foreach (var arc in node.InEdges) {
    118             var parent = arc.Target;
    119             // find the visual parent node that is closest to the current node in terms of vertical distance
    120             var visualParent = _visualNodeMap[parent].Where(p => p.Center.Y >= visualNode.Center.Y).OrderByDescending(p => p.Center.Y).Last();
    121             DashStyle style;
    122             if (visualParent.Data == visualNode.Data) { // if the graph nodes represent the same elite individual
    123               style = DashStyle.Dash;
    124             } else {
    125               style = node.InEdges.Count == 2 ? DashStyle.Solid : DashStyle.Dash;
    126             }
    127             var arcPen = new Pen(Color.Transparent) { DashStyle = style };
    128             _visualArcMap[Tuple.Create(visualParent, visualNode)] = AddArc(Chart, visualParent, visualNode, arcPen);
    129           }
    130         }
     107        }
     108
    131109        y -= Cy; // decrement vertical coordinate (because the origin is upside down)
    132         x = 0; // reset horizontal coordinate
     110      }
     111      // add arcs separately (to avoid some ordering problems)
     112      foreach (var node in _visualNodeMap.Keys) {
     113        var visualNode = _visualNodeMap[node][0];
     114        if (node.InEdges == null) continue;
     115
     116        foreach (var arc in node.InEdges) {
     117          var visualParent = _visualNodeMap[arc.Target][0];
     118          var pen = new Pen(Color.Transparent);
     119          _visualArcMap[Tuple.Create(visualParent, visualNode)] = AddArc(Chart, visualParent, visualNode, pen);
     120        }
     121      }
     122      // connect visual nodes representing the same elite individual with a line
     123      foreach (var list in _visualNodeMap.Values.Where(l => l.Count > 1)) {
     124        for (int i = 1; i != list.Count; ++i) {
     125          var pen = new Pen(Color.LightGray);
     126          _visualArcMap[Tuple.Create(list[i - 1], list[i])] = AddArc(Chart, list[i - 1], list[i], pen);
     127        }
    133128      }
    134129
     
    187182            node.Brush = new SolidBrush(node.ToColor());
    188183            if (node.IncomingArcs != null)
    189               foreach (var arc in node.IncomingArcs)
    190                 if (arc.Source.Data != arc.Target.Data && arc.Source == _visualNodeMap[arc.Source.Data][0]) {
     184              foreach (var arc in node.IncomingArcs) {
     185                // check if, in case of elites, the target node is the first visual representation of the elite
     186                // (for purposes of display consistency)
     187                bool isFirst = arc.Source == _visualNodeMap[arc.Source.Data][0];
     188                if (arc.Source.Data != arc.Target.Data && isFirst) {
    191189                  var start = new Point((int)arc.Start.X, (int)arc.Start.Y);
    192190                  var end = new Point((int)arc.End.X, (int)arc.End.Y);
    193191                  arc.Pen.Brush = new LinearGradientBrush(start, end, arc.Source.ToColor(), arc.Target.ToColor());
    194192                }
     193              }
    195194          }
    196195          // highlight descendants
     
    198197            node.Brush = new SolidBrush(node.ToColor());
    199198            if (node.OutgoingArcs != null)
    200               foreach (var arc in node.OutgoingArcs)
    201                 if (arc.Source.Data != arc.Target.Data && arc.Target == _visualNodeMap[arc.Target.Data][0]) {
     199              foreach (var arc in node.OutgoingArcs) {
     200                // check if, in case of elites, the target node is the first visual representation of the elite
     201                // (for purposes of display consistency)
     202                bool isFirst = arc.Target == _visualNodeMap[arc.Target.Data][0];
     203                if (arc.Source.Data != arc.Target.Data && isFirst) {
    202204                  var start = new Point((int)arc.Start.X, (int)arc.Start.Y);
    203205                  var end = new Point((int)arc.End.X, (int)arc.End.Y);
    204206                  arc.Pen.Brush = new LinearGradientBrush(start, end, arc.Source.ToColor(), arc.Target.ToColor());
    205207                }
     208              }
    206209          }
    207210        } else {
  • branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking.Views/3.4/GenealogyGraphView.cs

    r8213 r8236  
    115115          foreach (var node in fragment.IterateNodesBreadth()) {
    116116            var visualNode = symbolicExpressionTreeChart.GetVisualSymbolicExpressionTreeNode(node);
     117            if (visualNode == null)
     118              continue;
    117119            visualNode.FillColor = Color.LightGreen;
    118120          }
  • branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking.Views/3.4/VisualGenealogyGraphNode.cs

    r8213 r8236  
    2323using System.Collections.Generic;
    2424using System.Drawing;
     25using HeuristicLab.Common;
    2526using HeuristicLab.Visualization;
    2627
     
    7677
    7778    public Color ToColor() {
    78       return Color.FromArgb((int)((1 - Data.Quality) * 255), (int)(Data.Quality * 255), 0);
     79      //      return Color.FromArgb((int)((1 - Data.Quality) * 255), (int)(Data.Quality * 255), 0);
     80      int i = (int)(Data.Quality * ColorGradient.Colors.Count);
     81      if (i == ColorGradient.Colors.Count) --i;
     82      return ColorGradient.Colors[i];
    7983    }
    8084
  • branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/Analyzers/SymbolicExpressionTreeGenealogyAnalyzer.cs

    r8213 r8236  
    232232                         let quality = (DoubleValue)s.Variables["Quality"].Value
    233233                         orderby quality.Value descending
    234                          select new Tuple<ISymbolicExpressionTree, double>((ISymbolicExpressionTree)individual, quality.Value)).ToDictionary(t => t.Item1, t => t.Item2);
     234                         select Tuple.Create((ISymbolicExpressionTree)individual, quality.Value)).ToList();
    235235
    236236        // add all individuals to the evolutionary graph
    237237        int generation = Generations.Value;
    238         string label;
    239         if (generation == 0) {
    240           // at generation 0 no trace map is present (since no reproduction has taken place yet),
    241           // so we only add the initial individuals as nodes in the genealogy graph
    242           for (int i = 0; i != qualities.Count; ++i) {
    243             var tree = qualities.ElementAt(i).Key;
    244             label = (i + 1).ToString(CultureInfo.InvariantCulture);
    245             var node = new GenealogyGraphNode(tree) { Quality = qualities[tree], Label = label, Rank = generation, IsElite = i < Elites.Value };
    246             graph.AddNode(node);
    247           }
    248           return base.Apply();
    249         }
    250 
    251238        // add nodes to genealogy graph
    252239        for (int i = 0; i != qualities.Count; ++i) {
    253           var child = qualities.ElementAt(i).Key;
    254           label = (generation * qualities.Count + i + 1).ToString(CultureInfo.InvariantCulture);
    255           if (!graph.HasNode(child)) {
    256             var node = new GenealogyGraphNode(child) {
    257               Quality = qualities[child],
     240          var indiv = qualities[i].Item1;
     241          var label = (generation * qualities.Count + i + 1).ToString(CultureInfo.InvariantCulture);
     242          if (!graph.HasNode(indiv)) {
     243            var node = new GenealogyGraphNode(indiv) {
     244              Quality = qualities[i].Item2,
    258245              Label = label,
    259246              Rank = generation,
     
    262249            graph.AddNode(node);
    263250          }
    264           if (!GlobalTraceMap.ContainsKey(child)) continue;
    265           var parents = GlobalTraceMap[child].Cast<ISymbolicExpressionTree>();
    266 
     251          if (generation == 0) continue;
     252          if (!GlobalTraceMap.ContainsKey(indiv)) continue;
     253
     254          var parents = GlobalTraceMap[indiv].Cast<ISymbolicExpressionTree>();
    267255          foreach (var parent in parents) {
    268             object data = ((GenericWrapper<SymbolicExpressionTreeNode>)GlobalFragmentMap[child]).Content;
    269             graph.AddArc(parent, child, null, data);
     256            object data = ((GenericWrapper<SymbolicExpressionTreeNode>)GlobalFragmentMap[indiv]).Content;
    270257            if (GlobalTraceMap.ContainsKey(parent)) {
    271258              double quality = Evaluate(parent);
    272               var node = new GenealogyGraphNode(parent) { Quality = quality, Label = "", Rank = generation - 0.5 };
     259              var node = new GenealogyGraphNode(parent) { Quality = quality, Label = "X", Rank = generation - 0.5 };
    273260              graph.AddNode(node);
    274261              var pp = GlobalTraceMap[parent].Cast<SymbolicExpressionTree>();
     
    278265              }
    279266            }
     267            graph.AddArc(parent, indiv, null, data);
    280268          }
    281269        }
    282 
    283270        // clear trace and clone maps in preparation for the next generation
     271        if (generation == 0) return base.Apply();
    284272        if (this.Successor == null || !(this.Successor is SymbolicExpressionTreeFragmentsAnalyzer)) {
    285273          GlobalTraceMap.Clear();
  • branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/GenealogyGraph.cs

    r8213 r8236  
    3030namespace HeuristicLab.EvolutionaryTracking {
    3131  [Item("Genealogy graph", "Generic class for tracking the evolution of objects.")]
     32  [StorableClass]
    3233  public class GenealogyGraph<T> : NamedItem, IGenealogyGraph<T> where T : class {
     34    [Storable]
    3335    private readonly Dictionary<T, GenealogyGraphNode> _nodes;
    3436
     
    8284    public void AddNode(GenealogyGraphNode node) {
    8385      var t = (T)node.Data;
    84       if (HasNode(t)) return;
     86      if (HasNode(t))
     87        return;
    8588      _nodes[t] = node;
    8689    }
  • branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/SymbolicExpressionTreeGenealogyGraph.cs

    r8213 r8236  
    22using System.Linq;
    33using HeuristicLab.Common;
     4using HeuristicLab.Core;
    45using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
    56using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
     
    78
    89namespace HeuristicLab.EvolutionaryTracking {
     10  [Item("SymbolicExpressionTreeGenealogyGraph", "A genealogy graph for symbolic expression trees")]
     11  [StorableClass]
    912  public class SymbolicExpressionTreeGenealogyGraph : GenealogyGraph<ISymbolicExpressionTree> {
    1013    public SymbolicExpressionTreeGenealogyGraph() {
  • branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Selection/3.3/Plugin.cs

    r8213 r8236  
    2626  /// Plugin class for HeuristicLab.Selection plugin.
    2727  /// </summary>
    28   [Plugin("HeuristicLab.Selection", "3.3.6.7997")]
     28  [Plugin("HeuristicLab.Selection", "3.3.6.8213")]
    2929  [PluginFile("HeuristicLab.Selection-3.3.dll", PluginFileType.Assembly)]
    3030  [PluginDependency("HeuristicLab.Collections", "3.3")]
Note: See TracChangeset for help on using the changeset viewer.