Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
05/03/12 12:26:11 (12 years ago)
Author:
bburlacu
Message:

#1772: Implemented new View, improved functionality (tracking of fragments and operators)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/Analyzers/SymbolicExpressionTreeGenealogyAnalyzer.cs

    r7522 r7779  
    2222using System;
    2323using System.Collections.Generic;
     24using System.Drawing;
    2425using System.Globalization;
    2526using System.Linq;
     
    3637using HeuristicLab.Problems.DataAnalysis;
    3738using HeuristicLab.Problems.DataAnalysis.Symbolic;
    38 using HeuristicLab.Problems.DataAnalysis.Symbolic.Regression;
    3939using CloneMapType = HeuristicLab.Core.ItemDictionary<HeuristicLab.Core.IItem, HeuristicLab.Core.IItem>;
    4040using TraceMapType = HeuristicLab.Core.ItemDictionary<HeuristicLab.Core.IItem, HeuristicLab.Core.IItemList<HeuristicLab.Core.IItem>>;
     
    4747  [StorableClass]
    4848  public sealed class SymbolicExpressionTreeGenealogyAnalyzer : SingleSuccessorOperator, IAnalyzer {
     49    public enum GeneticOperator { Crossover, Mutation }
     50
    4951    private const string UpdateIntervalParameterName = "UpdateInterval";
    5052    private const string UpdateCounterParameterName = "UpdateCounter";
     
    213215        var gScope = ExecutionContext.Scope;
    214216        while (gScope.Parent != null) gScope = gScope.Parent;
    215         GenealogyGraph graph;
     217        SymbolicExpressionTreeGenealogyGraph graph;
    216218        if (!Results.ContainsKey(PopulationGraphResultParameterName)) {
    217           graph = new GenealogyGraph();
     219          graph = new SymbolicExpressionTreeGenealogyGraph();
    218220          Results.Add(new Result(PopulationGraphResultParameterName, PopulationGraphResultParameterDescription, graph));
    219221        } else {
    220           graph = (GenealogyGraph)Results[PopulationGraphResultParameterName].Value;
     222          graph = (SymbolicExpressionTreeGenealogyGraph)Results[PopulationGraphResultParameterName].Value;
    221223        }
    222224        // get tree quality values
     
    225227                         let quality = (DoubleValue)s.Variables["Quality"].Value
    226228                         orderby quality.Value descending
    227                          select new Tuple<IItem, double>(individual, quality.Value)).ToDictionary(t => t.Item1, t => t.Item2);
     229                         select new Tuple<ISymbolicExpressionTree, double>((ISymbolicExpressionTree)individual, quality.Value)).ToDictionary(t => t.Item1, t => t.Item2);
    228230
    229231        // add all individuals to the evolutionary graph
     
    232234
    233235        if (generation == 0) {
    234           // at generation 0 no trace map is present (since no reproduction has taken place yet),
    235           // so we only add the initial trees as nodes in the genealogy graph
     236          // at generation 0 no trace map is present (since no reproduction has taken place yet), so we only add the initial trees as nodes in the genealogy graph
    236237          for (int i = 0; i != qualities.Count; ++i) {
    237238            var tree = qualities.ElementAt(i).Key;
     
    242243        }
    243244
     245        // add nodes to genealogy graph
    244246        for (int i = 0; i != qualities.Count; ++i) {
    245247          var child = qualities.ElementAt(i).Key;
    246248          label = (generation * qualities.Count + i + 1).ToString(CultureInfo.InvariantCulture);
    247           if (i < Elites.Value) {
    248             if (graph.HasNode(child))
    249               graph.GetNode(child).Label += "\\n" + label;
    250             else
    251               graph.AddNode(child, qualities[child], label, generation, true);
    252           } else
    253             graph.AddNode(child, qualities[child], label, generation);
     249          if (!graph.HasNode(child)) graph.AddNode(child, qualities[child], label, generation, i < Elites.Value);
    254250          if (!GlobalTraceMap.ContainsKey(child)) continue;
    255251          var parents = GlobalTraceMap[child];
     252
    256253          foreach (var parent in parents) {
     254            int opType;
    257255            if (GlobalTraceMap.ContainsKey(parent)) {
    258256              double quality = Evaluate((ISymbolicExpressionTree)parent);
    259               graph.AddNode(parent, quality, "", generation - 0.5);
    260               foreach (var p in GlobalTraceMap[parent])
    261                 graph.AddArc(p, parent);
     257              graph.AddNode((ISymbolicExpressionTree)parent, quality, "", generation - 0.5);
     258              var pp = GlobalTraceMap[parent];
     259              foreach (var p in pp) {
     260                opType = pp.Count == 2 ? (int)GeneticOperator.Crossover : (int)GeneticOperator.Mutation;
     261                graph.AddArc((ISymbolicExpressionTree)p, (ISymbolicExpressionTree)parent, opType);
     262              }
    262263            }
    263             graph.AddArc(parent, child);
     264            opType = parents.Count == 2 ? (int)GeneticOperator.Crossover : (int)GeneticOperator.Mutation;
     265            graph.AddArc((ISymbolicExpressionTree)parent, child, opType);
    264266          }
    265267        }
    266268
     269        // clear trace and clone maps in preparation for the next generation
    267270        GlobalTraceMap.Clear();
    268271        GlobalCloneMap.Clear();
    269272
    270         #region end of the run
    271         bool maxGenerationsReached = (Generations.Value == MaximumGenerations.Value);
    272         bool isOsga = (SelectionPressure != null && MaximumSelectionPressure != null);
    273         bool maxSelectionPressureReached = isOsga && (SelectionPressure.Value >= MaximumSelectionPressure.Value);
    274         if (maxGenerationsReached || maxSelectionPressureReached) {
    275           var path = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
    276 
    277           // write whole graph to a dot file
    278           WriteDot(path + @"\lineage.dot", graph);
    279 
    280           // get genealogy of the best solution
    281           var bestSolution = (ISymbolicExpressionTree)qualities.First().Key;
    282           var genealogy = graph.GetNode(bestSolution).Genealogy();
    283           WriteDot(path + @"\bestlineage.dot", genealogy);
    284 
    285           // write the direct root lineage of the best solution (is it useful?)
    286 
    287           // calculate impact values of nodes in the best solution, attempt to trace those with high impact to their origins
    288           var calculator = new SymbolicRegressionSolutionValuesCalculator();
    289           var impactValues = calculator.CalculateImpactValues(bestSolution, SymbolicExpressionInterpreter, SymbolicRegressionProblemData, 0, 0);
    290           foreach (var pair in impactValues.Where(pair => !(pair.Key is ConstantTreeNode || pair.Key is VariableTreeNode) && pair.Value > 0.9)) {
    291             var node = pair.Key;
    292 
    293             foreach (var ancestor in genealogy.Keys) {
    294               graph.GetNode(ancestor).Color = ContainsSubtree(ancestor as ISymbolicExpressionTree, node) ? new Color { R = 0, G = 0, B = 150 } : new Color { R = 255, G = 255, B = 255 };
    295             }
    296           }
    297           WriteDot(path + @"\impactancestry.dot", genealogy);
    298 
    299           // trim the graph
    300           // exclude the individuals of the last generation
    301           var individuals = graph.Keys.Except(qualities.Select(x => x.Key)).ToList();
    302           bool done = false;
    303           while (!done) {
    304             done = true;
    305             foreach (var ind in individuals) {
    306               // if node has no outgoing connections (absence of offspring), remove it from the graph
    307               var node = graph.GetNode(ind);
    308               if (node == null) continue;
    309               if (node.OutEdges == null) {
    310                 done = false; // we still have "dead" nodes
    311                 graph.RemoveNode(ind);
    312               }
    313             }
    314           }
    315           WriteDot(path + @"\trimmedlineage.dot", graph);
    316         }
     273        #region end of the run (code for writing results to dot files)
     274        //bool maxGenerationsReached = (Generations.Value == MaximumGenerations.Value);
     275        //bool isOsga = (SelectionPressure != null && MaximumSelectionPressure != null);
     276        //bool maxSelectionPressureReached = isOsga && (SelectionPressure.Value >= MaximumSelectionPressure.Value);
     277        //if (maxGenerationsReached || maxSelectionPressureReached) {
     278        //  var path = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
     279
     280        //  // write whole graph to a dot file
     281        //  WriteDot(path + @"\lineage.dot", graph);
     282
     283        //  // get genealogy of the best solution
     284        //  var bestSolution = (ISymbolicExpressionTree)qualities.First().Key;
     285        //  var genealogy = graph.GetNode(bestSolution).Ancestors();
     286        //  //WriteDot(path + @"\bestlineage.dot", genealogy);
     287
     288        //  // write the direct root lineage of the best solution (is it useful?)
     289
     290        //  // calculate impact values of nodes in the best solution, attempt to trace those with high impact to their origins
     291        //  var calculator = new SymbolicRegressionSolutionValuesCalculator();
     292        //  var impactValues = calculator.CalculateImpactValues(bestSolution, SymbolicExpressionInterpreter, SymbolicRegressionProblemData, 0, 0);
     293        //  foreach (var pair in impactValues.Where(pair => !(pair.Key is ConstantTreeNode || pair.Key is VariableTreeNode)).OrderByDescending(pair => pair.Value).Take(2)) {
     294        //    var node = pair.Key;
     295        //  }
     296        //  //WriteDot(path + @"\impactancestry.dot", genealogy);
     297
     298        //  // trim the graph
     299        //  // exclude the individuals of the last generation
     300        //  var individuals = graph.Keys.Except(qualities.Select(x => x.Key)).ToList();
     301        //  bool done = false;
     302        //  while (!done) {
     303        //    done = true;
     304        //    foreach (var ind in individuals) {
     305        //      // if node has no outgoing connections (absence of offspring), remove it from the graph
     306        //      var node = graph.GetNode(ind);
     307        //      if (node == null) continue;
     308        //      if (node.OutEdges == null) {
     309        //        done = false; // we still have "dead" nodes
     310        //        graph.RemoveNode(ind);
     311        //      }
     312        //    }
     313        //  }
     314        //  WriteDot(path + @"\trimmedlineage.dot", graph);
     315        //}
    317316        #endregion
    318317      }
     
    336335
    337336    #region Export to dot file
    338     private static void WriteDot(string path, GenealogyGraph graph) {
     337    private static void WriteDot(string path, SymbolicExpressionTreeGenealogyGraph graph) {
    339338      using (var file = new System.IO.StreamWriter(path)) {
    340339        string nl = Environment.NewLine;
    341         file.WriteLine("digraph \"lineage " + graph.AverageDegree.ToString(CultureInfo.InvariantCulture) + "\" {" + nl +
    342                        "ratio=auto;" + nl +
    343                        "mincross=2.0");
     340        file.WriteLine("digraph \"lineage " + graph.AverageDegree.ToString(CultureInfo.InvariantCulture) + "\" {" + nl + "ratio=auto;" + nl + "mincross=2.0");
    344341        file.WriteLine("\tnode [shape=circle,label=\"\",style=filled]");
    345342
    346343        foreach (var node in graph.Values) {
    347           string fillColor = String.Format("#{0:x2}{1:x2}{2:x2}", node.Color.R, node.Color.G, node.Color.B);
     344          var color = Color.FromArgb((int)((1 - node.Quality) * 255), (int)(node.Quality * 255), 0);
     345          string fillColor = String.Format("#{0:x2}{1:x2}{2:x2}", color.R, color.G, color.B);
    348346          string shape = "circle";
    349347          if (node.IsElite)
     
    353351            continue;
    354352          foreach (var edge in node.InEdges) {
    355             var edgeStyle = node.InEdges.Count == 1 ? "dashed" : String.Empty;
     353            //var edgeStyle = node.InEdges.Count == 1 ? "dashed" : String.Empty;
     354            var edgeStyle = String.Empty;
    356355            file.WriteLine("\t\"" + edge.Target.Id + "\" -> \"" + node.Id + "\" [arrowsize=.5, color=\"" + fillColor + "\", style=\"" + edgeStyle + "\"];");
    357356          }
     
    370369    #endregion
    371370
    372     #region Allele tracking
    373     private bool ContainsSubtree(ISymbolicExpressionTree tree, ISymbolicExpressionTreeNode node) {
    374       return tree.IterateNodesPostfix().Where(n => n.Symbol == node.Symbol && n.GetLength() == node.GetLength())
    375                                        .Where(n => n.Subtrees.Any() && node.Subtrees.Any())
    376                                        .Any(n => n.Subtrees.First().Symbol == node.Subtrees.First().Symbol);
    377     }
    378     #endregion
    379 
    380371    #region Extra / not really needed
     372    // method of iterating tree nodes in a breadth-wise manner
    381373    private IEnumerable<ISymbolicExpressionTreeNode> IterateNodes(ISymbolicExpressionTree tree) {
    382374      return IterateNodes(tree.Root);
Note: See TracChangeset for help on using the changeset viewer.