Index: /branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/Analyzers/Fragments/SymbolicExpressionTreeFragmentLengthsAnalyzer.cs
===================================================================
--- /branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/Analyzers/Fragments/SymbolicExpressionTreeFragmentLengthsAnalyzer.cs	(revision 9238)
+++ /branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/Analyzers/Fragments/SymbolicExpressionTreeFragmentLengthsAnalyzer.cs	(revision 9238)
@@ -0,0 +1,138 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Analysis;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+// type definitions for convenience
+using CloneMapType = HeuristicLab.Core.ItemDictionary<HeuristicLab.Core.IItem, HeuristicLab.Core.IItem>;
+using TraceMapType = HeuristicLab.Core.ItemDictionary<HeuristicLab.Core.IItem, HeuristicLab.Core.IItemList<HeuristicLab.Core.IItem>>;
+
+namespace HeuristicLab.EvolutionaryTracking {
+  /// <summary>
+  /// An operator that gathers information on tree fragments that get passed from one generation to the next via genetic operators
+  /// (Tracking of genetic variance and heredity)
+  /// </summary>
+  [Item("SymbolicExpressionTreeFragmentLengthAnalyzer", "An operator that provides statistics about fragment lengths")]
+  [StorableClass]
+  public sealed class SymbolicExpressionTreeFragmentLengthAnalyzer : SymbolicExpressionTreeFragmentsAnalyzer {
+    private const string FragmentLengthsParameterName = "Fragment Lengths";
+    // impact values calculator
+    public ILookupParameter<DataTable> FragmentLengthsParameter { get { return (ILookupParameter<DataTable>)Parameters[FragmentLengthsParameterName]; } }
+    public DataTable FragmentLengths {
+      get { return FragmentLengthsParameter.ActualValue; }
+      set { FragmentLengthsParameter.ActualValue = value; }
+    }
+
+    [StorableConstructor]
+    private SymbolicExpressionTreeFragmentLengthAnalyzer(bool deserializing) : base(deserializing) { }
+    private SymbolicExpressionTreeFragmentLengthAnalyzer(SymbolicExpressionTreeFragmentLengthAnalyzer original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SymbolicExpressionTreeFragmentLengthAnalyzer(this, cloner);
+    }
+    public SymbolicExpressionTreeFragmentLengthAnalyzer()
+      : base() {
+      #region Add parameters
+      Parameters.Add(new LookupParameter<DataTable>(FragmentLengthsParameterName));
+      #endregion
+
+      UpdateCounterParameter.Hidden = true;
+      UpdateIntervalParameter.Hidden = true;
+    }
+    #region After deserialization code
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+    }
+
+    #endregion
+    #region IStatefulItem members
+    public override void InitializeState() {
+      base.InitializeState();
+      UpdateCounter.Value = 0;
+    }
+
+    public override void ClearState() {
+      base.ClearState();
+      UpdateCounter.Value = 0;
+    }
+    #endregion
+
+    public override IOperation Apply() {
+      UpdateCounter.Value++;
+      if (UpdateCounter.Value == UpdateInterval.Value) {
+        UpdateCounter.Value = 0; // reset counter
+        if (Generations.Value > 1) {
+          SecondaryTraceMap = SecondaryTraceMap ?? new TraceMapType();
+          SecondaryFragmentMap = SecondaryFragmentMap ?? new CloneMapType();
+          SecondaryCloneMap = SecondaryCloneMap ?? new CloneMapType();
+
+          InitializeParameters();
+          InitializeRows();
+
+          var fragmentLengths = (from m in SecondaryFragmentMap
+                                 let fragment = (IFragment)m.Value
+                                 where fragment.Root != null
+                                 select fragment.Length
+                               ).ToList();
+
+          // fragments of selected offspring
+          var selected = new HashSet<ISymbolicExpressionTree>(GlobalTraceMap.Values.SelectMany(list => list.Cast<ISymbolicExpressionTree>()));
+          var goodFragmentlengths = (from m in SecondaryFragmentMap
+                                     let tree = (ISymbolicExpressionTree)m.Key
+                                     let fragment = (IFragment)m.Value
+                                     where fragment.Root != null
+                                     where selected.Contains(tree)
+                                     select fragment.Length
+                                    ).ToList();
+
+          FragmentLengths.Rows["Average fragment length (all)"].Values.Add(fragmentLengths.Count > 0 ? fragmentLengths.Average() : 0.0);
+          FragmentLengths.Rows["Average fragment length (good)"].Values.Add(goodFragmentlengths.Count > 0 ? goodFragmentlengths.Average() : 0.0);
+        }
+      }
+      return base.Apply();
+    }
+
+    protected override void InitializeParameters() {
+      var results = ResultsParameter.ActualValue;
+      if (!results.ContainsKey("Fragment lengths")) {
+        FragmentLengths = FragmentLengths ?? new DataTable("Fragment lengths") { VisualProperties = { YAxisTitle = "Number of nodes" } };
+        results.Add(new Result("Fragment lengths", FragmentLengths));
+      }
+      base.InitializeParameters();
+    }
+
+    private void InitializeRows() {
+      string[] rowNames =
+        {
+          "Average fragment length (good)", "Average fragment length (all)"
+        };
+      foreach (var rowName in rowNames.Where(rowName => !FragmentLengths.Rows.ContainsKey(rowName))) {
+        FragmentLengths.Rows.Add(new DataRow(rowName) { VisualProperties = { StartIndexZero = true } });
+      }
+    }
+  } //SymbolicExpressionTreeFragmentLengthAnalyzer
+}
Index: /branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/Analyzers/Fragments/SymbolicExpressionTreeFragmentsAnalyzer.cs
===================================================================
--- /branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/Analyzers/Fragments/SymbolicExpressionTreeFragmentsAnalyzer.cs	(revision 9238)
+++ /branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/Analyzers/Fragments/SymbolicExpressionTreeFragmentsAnalyzer.cs	(revision 9238)
@@ -0,0 +1,315 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.DataAnalysis;
+using HeuristicLab.Problems.DataAnalysis.Symbolic;
+// type definitions for convenience
+using HeuristicLab.Problems.DataAnalysis.Symbolic.Regression;
+using CloneMapType = HeuristicLab.Core.ItemDictionary<HeuristicLab.Core.IItem, HeuristicLab.Core.IItem>;
+using TraceMapType = HeuristicLab.Core.ItemDictionary<HeuristicLab.Core.IItem, HeuristicLab.Core.IItemList<HeuristicLab.Core.IItem>>;
+
+namespace HeuristicLab.EvolutionaryTracking {
+  /// <summary>
+  /// An operator that gathers information on tree fragments that get passed from one generation to the next via genetic operators
+  /// (Tracking of genetic variance and heredity)
+  /// </summary>
+  [Item("SymbolicExpressionTreeFragmentsAnalyzer", "An operator that provides statistics about crossover fragments")]
+  [StorableClass]
+  public abstract class SymbolicExpressionTreeFragmentsAnalyzer : SingleSuccessorOperator, IAnalyzer {
+    #region Parameter names
+    protected const string UpdateIntervalParameterName = "UpdateInterval";
+    protected const string UpdateCounterParameterName = "UpdateCounter";
+    protected const string ResultsParameterName = "Results";
+    protected const string SecondaryTraceMapParameterName = "SecondaryTraceMap";
+    protected const string SecondaryFragmentMapParameterName = "SecondaryFragmentMap";
+    protected const string SecondaryCloneMapParameterName = "SecondaryCloneMap";
+    protected const string GlobalTraceMapParameterName = "GlobalTraceMap";
+    protected const string GlobalTraceMapParameterDescription = "Global map of trees and their parents.";
+    protected const string GlobalCloneMapParameterName = "GlobalCloneMap";
+    protected const string GlobalCloneMapParameterDescription = "Global map of trees and their clones";
+    protected const string GlobalFragmentMapParameterName = "GlobalFragmentMap";
+    protected const string GlobalFragmentMapParameterDescription = "Global map of trees and their respective fragments.";
+    protected const string GenerationsParameterName = "Generations";
+    protected const string SymbolicExpressionInterpreterParameterName = "SymbolicExpressionTreeInterpreter";
+    protected const string SymbolicRegressionProblemDataParameterName = "ProblemData";
+    #endregion
+
+    // impact values calculator
+    private readonly SymbolicRegressionSolutionImpactValuesCalculator calculator = new SymbolicRegressionSolutionImpactValuesCalculator();
+
+    #region Parameter properties
+    public ValueParameter<IntValue> UpdateIntervalParameter {
+      get { return (ValueParameter<IntValue>)Parameters[UpdateIntervalParameterName]; }
+    }
+    public ValueParameter<IntValue> UpdateCounterParameter {
+      get { return (ValueParameter<IntValue>)Parameters[UpdateCounterParameterName]; }
+    }
+    public LookupParameter<ResultCollection> ResultsParameter {
+      get { return (LookupParameter<ResultCollection>)Parameters[ResultsParameterName]; }
+    }
+    public LookupParameter<IntValue> GenerationsParameter {
+      get { return (LookupParameter<IntValue>)Parameters[GenerationsParameterName]; }
+    }
+    // tracking structures
+    public LookupParameter<TraceMapType> GlobalTraceMapParameter {
+      get { return (LookupParameter<TraceMapType>)Parameters[GlobalTraceMapParameterName]; }
+    }
+    public LookupParameter<CloneMapType> GlobalCloneMapParameter {
+      get { return (LookupParameter<CloneMapType>)Parameters[GlobalCloneMapParameterName]; }
+    }
+    public LookupParameter<CloneMapType> GlobalFragmentMapParameter {
+      get { return (LookupParameter<CloneMapType>)Parameters[GlobalFragmentMapParameterName]; }
+    }
+    // auxiliary structures for tracking fragments and individuals from the previous generation
+    // (this is needed because tracking is done in connection to the current generation, i.e., for 
+    // counting "successful" offspring and fragments
+    public LookupParameter<TraceMapType> SecondaryTraceMapParameter {
+      get { return (LookupParameter<TraceMapType>)Parameters[SecondaryTraceMapParameterName]; }
+    }
+    public LookupParameter<CloneMapType> SecondaryFragmentMapParameter {
+      get { return (LookupParameter<CloneMapType>)Parameters[SecondaryFragmentMapParameterName]; }
+    }
+    public LookupParameter<CloneMapType> SecondaryCloneMapParameter {
+      get { return (LookupParameter<CloneMapType>)Parameters[SecondaryCloneMapParameterName]; }
+    }
+    // problem data, interpreter and evaluator
+    public LookupParameter<SymbolicDataAnalysisExpressionTreeInterpreter> SymbolicExpressionInterpreterParameter {
+      get { return (LookupParameter<SymbolicDataAnalysisExpressionTreeInterpreter>)Parameters[SymbolicExpressionInterpreterParameterName]; }
+    }
+    public LookupParameter<RegressionProblemData> SymbolicRegressionProblemDataParameter {
+      get { return (LookupParameter<RegressionProblemData>)Parameters[SymbolicRegressionProblemDataParameterName]; }
+    }
+    #endregion
+
+    #region Parameters
+    public bool EnabledByDefault {
+      get { return true; }
+    }
+    public IntValue UpdateInterval {
+      get { return UpdateIntervalParameter.Value; }
+    }
+    public IntValue UpdateCounter {
+      get { return UpdateCounterParameter.Value; }
+    }
+    public ResultCollection Results {
+      get { return ResultsParameter.ActualValue; }
+    }
+    public CloneMapType GlobalCloneMap {
+      get { return GlobalCloneMapParameter.ActualValue; }
+    }
+    public TraceMapType GlobalTraceMap {
+      get { return GlobalTraceMapParameter.ActualValue; }
+    }
+    public TraceMapType SecondaryTraceMap {
+      get { return SecondaryTraceMapParameter.ActualValue; }
+      set { SecondaryTraceMapParameter.ActualValue = value; }
+    }
+    public CloneMapType SecondaryFragmentMap {
+      get { return SecondaryFragmentMapParameter.ActualValue; }
+      set { SecondaryFragmentMapParameter.ActualValue = value; }
+    }
+    public CloneMapType SecondaryCloneMap {
+      get { return SecondaryCloneMapParameter.ActualValue; }
+      set { SecondaryCloneMapParameter.ActualValue = value; }
+    }
+    public CloneMapType GlobalFragmentMap {
+      get { return GlobalFragmentMapParameter.ActualValue; }
+    }
+    public IntValue Generations {
+      get { return GenerationsParameter.ActualValue; }
+    }
+    public SymbolicDataAnalysisExpressionTreeInterpreter SymbolicExpressionInterpreter {
+      get { return SymbolicExpressionInterpreterParameter.ActualValue; }
+    }
+    public RegressionProblemData SymbolicRegressionProblemData {
+      get { return SymbolicRegressionProblemDataParameter.ActualValue; }
+    }
+    #endregion
+
+    [StorableConstructor]
+    protected SymbolicExpressionTreeFragmentsAnalyzer(bool deserializing) : base(deserializing) { }
+
+    protected SymbolicExpressionTreeFragmentsAnalyzer(SymbolicExpressionTreeFragmentsAnalyzer original, Cloner cloner) : base(original, cloner) { }
+
+    protected SymbolicExpressionTreeFragmentsAnalyzer()
+      : base() {
+      #region Add parameters
+      // analyzer update counter and update interval
+      Parameters.Add(new ValueParameter<IntValue>(UpdateIntervalParameterName, "The interval in which the tree length analysis should be applied.", new IntValue(1)));
+      Parameters.Add(new ValueParameter<IntValue>(UpdateCounterParameterName, "The value which counts how many times the operator was called since the last update", new IntValue(0)));
+      // tracking
+      Parameters.Add(new LookupParameter<TraceMapType>(GlobalTraceMapParameterName, GlobalTraceMapParameterDescription));
+      Parameters.Add(new LookupParameter<CloneMapType>(GlobalCloneMapParameterName, GlobalCloneMapParameterDescription));
+      Parameters.Add(new LookupParameter<CloneMapType>(GlobalFragmentMapParameterName, GlobalFragmentMapParameterDescription));
+      // secondary tracking 
+      Parameters.Add(new LookupParameter<TraceMapType>(SecondaryTraceMapParameterName, GlobalTraceMapParameterDescription));
+      Parameters.Add(new LookupParameter<CloneMapType>(SecondaryCloneMapParameterName, GlobalCloneMapParameterDescription));
+      Parameters.Add(new LookupParameter<CloneMapType>(SecondaryFragmentMapParameterName, GlobalFragmentMapParameterDescription));
+      // impact calculation
+      Parameters.Add(new LookupParameter<SymbolicDataAnalysisExpressionTreeInterpreter>(SymbolicExpressionInterpreterParameterName, "Interpreter for symbolic expression trees"));
+      Parameters.Add(new LookupParameter<RegressionProblemData>(SymbolicRegressionProblemDataParameterName, "The symbolic data analysis problem."));
+      // fragment statistics parameters
+      Parameters.Add(new ValueLookupParameter<ResultCollection>(ResultsParameterName, "The results collection where the analysis values should be stored."));
+      Parameters.Add(new LookupParameter<IntValue>(GenerationsParameterName, "The number of generations so far."));
+      #endregion
+
+      UpdateCounterParameter.Hidden = true;
+      UpdateIntervalParameter.Hidden = true;
+
+    }
+    #region After deserialization code
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      // check if all the parameters are present and accounted for 
+      if (!Parameters.ContainsKey(UpdateIntervalParameterName)) {
+        Parameters.Add(new ValueParameter<IntValue>(UpdateIntervalParameterName, "The interval in which the tree length analysis should be applied.", new IntValue(1)));
+      }
+      if (!Parameters.ContainsKey(UpdateCounterParameterName)) {
+        Parameters.Add(new ValueParameter<IntValue>(UpdateCounterParameterName, "The value which counts how many times the operator was called since the last update", new IntValue(0)));
+        UpdateCounterParameter.Hidden = true;
+      }
+    }
+    #endregion
+    #region IStatefulItem members
+    public override void InitializeState() {
+      base.InitializeState();
+      UpdateCounter.Value = 0;
+    }
+
+    public override void ClearState() {
+      base.ClearState();
+      UpdateCounter.Value = 0;
+    }
+    #endregion
+
+    /* A small description of the way this analyzer works
+     * 
+     * We keep 3 maps in the global scope: the GlobalTraceMap, the GlobalFragmentMap and the GlobalCloneMap that are updated on each step: selection, crossover, mutation
+     * These maps provide information about the children, parents and transferred fragments as follows:
+     * 
+     * 1) GlobalCloneMap
+     *    This data structure provides the basis for tracking. In the selection step, every selected individual gets cloned and transferred into the recombination pool.
+     *    The GlobalCloneMap keeps track of clones by mapping them to the original individuals. This is an essential step for building the genealogy graph. Using this
+     *    structure we can find out how many times each individual was selected. 
+     *    The GlobalCloneMap consists of Key-Value pairs Clone->Original
+     *
+     * 2) GlobalTraceMap
+     *    Keeps information in the form of key-value pairs Child->{Parents}, where {Parents} is a set consisting of 
+     *      - one parent individual (in the case of mutation), by language abuse we say that the individual that mutation acted on is the parent,
+     *        and the resulting individual is the child
+     *      - two parent individuals (in the case of crossover), named Parent0 and Parent1. Parent0 is the individual that crossover acts on by replacing 
+     *        one of its subtrees with a compatible subtree, randomly selected from Parent1
+     *
+     *    CROSSOVER
+     *        Parent0     Parent1                                                                    {Parents}
+     *           \           /                                                                           ^
+     *            \       fragment (inserted from Parent1 into Parent0 to create the Child)              ^    [Mapping provided by the GlobalTraceMap]
+     *             \       /                                                                             ^
+     *              \     /                                                                              ^
+     *               Child                                                                             Child
+     *               
+     *    MUTATION
+     *        Parent0
+     *           |
+     *           |    [mutation acts on a random node/subtree in the 'parent' individual
+     *           |
+     *         Child
+     *         
+     *    Since crossover and mutation act on individuals in the recombination pool (which in fact are clones of individuals from the previous generation), the GlobalTraceMap
+     *    is populated with values given by the mappings in the GlobalCloneMap, so that the original parent for each child is known.
+     *    
+     *  3) GlobalFragmentMap
+     *     Keeps information in the form of Key-Value pairs about an individual and its respective fragment 
+     *     (ie., the subtree received via crossover or created/altered by mutation)
+     * */
+
+    public override IOperation Apply() {
+      // save the current generation so it can be compared to the following one, next time the analyzer is applied
+      SecondaryTraceMap = SecondaryTraceMap ?? new TraceMapType();
+      SecondaryCloneMap = SecondaryCloneMap ?? new CloneMapType();
+      SecondaryFragmentMap = SecondaryFragmentMap ?? new CloneMapType();
+
+      SecondaryTraceMap.Clear();
+      if (GlobalTraceMap != null)
+        foreach (var m in GlobalTraceMap)
+          SecondaryTraceMap.Add(m.Key, m.Value);
+
+      SecondaryCloneMap.Clear();
+      if (GlobalCloneMap != null)
+        foreach (var m in GlobalCloneMap)
+          SecondaryCloneMap.Add(m.Key, m.Value);
+
+      SecondaryFragmentMap.Clear();
+      if (GlobalFragmentMap != null)
+        foreach (var m in GlobalFragmentMap)
+          SecondaryFragmentMap.Add(m.Key, m.Value);
+
+      return base.Apply();
+    }
+
+    protected virtual void InitializeParameters() {
+      #region Init parameters
+
+      #endregion
+    }
+
+    private static int VisitationLength(ISymbolicExpressionTree tree) {
+      return VisitationLength(tree.Root);
+    }
+
+    private static int VisitationLength(ISymbolicExpressionTreeNode node) {
+      return node.IterateNodesBreadth().Sum(n => n.GetLength());
+    }
+
+    #region Similarity computations
+    /// <summary>
+    /// Provide a measure of how similar the fragments that get passed by crossover from one generation to the next are. 
+    /// </summary>
+    /// <param name="fragments">The symbolic expression tree fragments</param>
+    /// <param name="comparer">The node similarity comparer</param>
+    /// <returns>The average number of similar fragments</returns>
+    private static double CalculateSimilarity(IList<IFragment> fragments, SymbolicExpressionTreeNodeSimilarityComparer comparer) {
+      var visited = new bool[fragments.Count];
+      int groups = 0;
+      for (int i = 0; i != fragments.Count - 1; ++i) {
+        if (visited[i]) continue;
+        for (int j = i + 1; j != fragments.Count; ++j) {
+          if (visited[j]) continue;
+          if (fragments[i].Root.IsSimilarTo(fragments[j].Root, comparer))
+            visited[j] = true;
+        }
+        ++groups;
+      }
+      return (double)fragments.Count / groups;
+    }
+    #endregion
+  } //SymbolicExpressionTreeFragmentsAnalyzer
+}
Index: /branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/Analyzers/Fragments/SymbolicExpressionTreeRelativeFragmentDepthAnalyzer.cs
===================================================================
--- /branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/Analyzers/Fragments/SymbolicExpressionTreeRelativeFragmentDepthAnalyzer.cs	(revision 9238)
+++ /branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/Analyzers/Fragments/SymbolicExpressionTreeRelativeFragmentDepthAnalyzer.cs	(revision 9238)
@@ -0,0 +1,138 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Analysis;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+// type definitions for convenience
+using CloneMapType = HeuristicLab.Core.ItemDictionary<HeuristicLab.Core.IItem, HeuristicLab.Core.IItem>;
+using TraceMapType = HeuristicLab.Core.ItemDictionary<HeuristicLab.Core.IItem, HeuristicLab.Core.IItemList<HeuristicLab.Core.IItem>>;
+
+namespace HeuristicLab.EvolutionaryTracking {
+  /// <summary>
+  /// An operator that gathers information on tree fragments that get passed from one generation to the next via genetic operators
+  /// (Tracking of genetic variance and heredity)
+  /// </summary>
+  [Item("SymbolicExpressionTreeRelativeFragmentDepthAnalyzer", "An operator that provides statistics about crossover fragments")]
+  [StorableClass]
+  public sealed class SymbolicExpressionTreeRelativeFragmentDepthAnalyzer : SymbolicExpressionTreeFragmentsAnalyzer {
+    private const string RelativeFragmentDepthParameterName = "Relative fragment depth";
+    public ILookupParameter<DataTable> RelativeFragmentDepthParameter { get { return (ILookupParameter<DataTable>)Parameters[RelativeFragmentDepthParameterName]; } }
+
+    public DataTable RelativeFragmentDepths {
+      get { return RelativeFragmentDepthParameter.ActualValue; }
+      set { RelativeFragmentDepthParameter.ActualValue = value; }
+    }
+
+    [StorableConstructor]
+    private SymbolicExpressionTreeRelativeFragmentDepthAnalyzer(bool deserializing) : base(deserializing) { }
+    private SymbolicExpressionTreeRelativeFragmentDepthAnalyzer(SymbolicExpressionTreeRelativeFragmentDepthAnalyzer original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SymbolicExpressionTreeRelativeFragmentDepthAnalyzer(this, cloner);
+    }
+    public SymbolicExpressionTreeRelativeFragmentDepthAnalyzer()
+      : base() {
+      #region Add parameters
+      Parameters.Add(new LookupParameter<DataTable>(RelativeFragmentDepthParameterName));
+      #endregion
+
+      UpdateCounterParameter.Hidden = true;
+      UpdateIntervalParameter.Hidden = true;
+
+    }
+    #region After deserialization code
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+    }
+
+    #endregion
+    #region IStatefulItem members
+    public override void InitializeState() {
+      base.InitializeState();
+      UpdateCounter.Value = 0;
+    }
+
+    public override void ClearState() {
+      base.ClearState();
+      UpdateCounter.Value = 0;
+    }
+    #endregion
+
+    public override IOperation Apply() {
+      UpdateCounter.Value++;
+      if (UpdateCounter.Value == UpdateInterval.Value) {
+        UpdateCounter.Value = 0; // reset counter
+        if (Generations.Value > 1) {
+          SecondaryTraceMap = SecondaryTraceMap ?? new TraceMapType();
+          SecondaryFragmentMap = SecondaryFragmentMap ?? new CloneMapType();
+          SecondaryCloneMap = SecondaryCloneMap ?? new CloneMapType();
+
+          InitializeParameters();
+          InitializeRows();
+
+          var fragmentDepths = (from m in SecondaryFragmentMap
+                                let tree = (ISymbolicExpressionTree)m.Key
+                                let fragment = (IFragment)m.Value
+                                where fragment.Root != null
+                                select tree.Root.GetBranchLevel(fragment.Root)
+                               ).ToList();
+
+          // fragments of selected offspring
+          var selected = new HashSet<ISymbolicExpressionTree>(GlobalTraceMap.Values.SelectMany(list => list.Cast<ISymbolicExpressionTree>()));
+          var goodFragmentDepths = (from m in SecondaryFragmentMap
+                                    let tree = (ISymbolicExpressionTree)m.Key
+                                    let fragment = (IFragment)m.Value
+                                    where fragment.Root != null
+                                    where selected.Contains(tree)
+                                    select tree.Root.GetBranchLevel(fragment.Root)
+                                   ).ToList();
+
+          RelativeFragmentDepths.Rows["Average relative fragment depth (all)"].Values.Add(fragmentDepths.Count > 0 ? fragmentDepths.Average() : 0.0);
+          RelativeFragmentDepths.Rows["Average relative fragment depth (good)"].Values.Add(goodFragmentDepths.Count > 0 ? goodFragmentDepths.Average() : 0.0);
+        }
+      }
+      return base.Apply();
+    }
+
+    protected override void InitializeParameters() {
+      var results = ResultsParameter.ActualValue;
+      if (!results.ContainsKey("Relative fragment depths")) {
+        RelativeFragmentDepths = RelativeFragmentDepths ?? new DataTable("Relative fragment depths") { VisualProperties = { YAxisTitle = "Relative depth" } };
+        results.Add(new Result("Relative fragment depths", RelativeFragmentDepths));
+      }
+      base.InitializeParameters();
+    }
+
+    private void InitializeRows() {
+      string[] rowNames = { "Average relative fragment depth (good)", "Average relative fragment depth (all)" };
+      foreach (var rowName in rowNames.Where(rowName => !RelativeFragmentDepths.Rows.ContainsKey(rowName))) {
+        RelativeFragmentDepths.Rows.Add(new DataRow(rowName) { VisualProperties = { StartIndexZero = true } });
+      }
+    }
+  } //SymbolicExpressionTreeFragmentLengthAnalyzer
+}
Index: /branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/Analyzers/GeneticOperatorImprovementAnalyzer.cs
===================================================================
--- /branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/Analyzers/GeneticOperatorImprovementAnalyzer.cs	(revision 9238)
+++ /branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/Analyzers/GeneticOperatorImprovementAnalyzer.cs	(revision 9238)
@@ -0,0 +1,191 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Analysis;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.DataAnalysis.Symbolic.Regression;
+
+namespace HeuristicLab.EvolutionaryTracking {
+  /// An analyzer that looks at individual lineages in the genealogy graph
+  /// </summary>
+  [Item("GeneticOperatorImprovementAnalyzer", "An operator that records the average success of genetic operators such as crossover and mutation.")]
+  [StorableClass]
+  class GeneticOperatorImprovementAnalyzer : SingleSuccessorOperator, IAnalyzer {
+    #region Parameter names
+    private const string UpdateIntervalParameterName = "UpdateInterval";
+    private const string UpdateCounterParameterName = "UpdateCounter";
+    private const string ResultsParameterName = "Results";
+    private const string GenerationsParameterName = "Generations";
+    private const string PopulationGraphParameterName = "PopulationGraph";
+    private const string GeneticOperatorsAverageImprovementResultName = "GeneticOperatorsAverageImprovement";
+    private const string UpdateConstantsInIntermediateNodesParameterName = "UpdateConstantsInIntermediateNodes";
+    #endregion
+
+    #region Parameter properties
+    public ValueParameter<IntValue> UpdateIntervalParameter {
+      get { return (ValueParameter<IntValue>)Parameters[UpdateIntervalParameterName]; }
+    }
+    public ValueParameter<IntValue> UpdateCounterParameter {
+      get { return (ValueParameter<IntValue>)Parameters[UpdateCounterParameterName]; }
+    }
+    public ValueParameter<BoolValue> UpdateConstantsInIntermediateNodesParameter {
+      get { return (ValueParameter<BoolValue>)Parameters[UpdateConstantsInIntermediateNodesParameterName]; }
+    }
+    public LookupParameter<ResultCollection> ResultsParameter {
+      get { return (LookupParameter<ResultCollection>)Parameters[ResultsParameterName]; }
+    }
+    public LookupParameter<IntValue> GenerationsParameter {
+      get { return (LookupParameter<IntValue>)Parameters[GenerationsParameterName]; }
+    }
+    #endregion
+
+    #region Properties
+    public IntValue UpdateInterval {
+      get { return UpdateIntervalParameter.Value; }
+    }
+    public IntValue UpdateCounter {
+      get { return UpdateCounterParameter.Value; }
+    }
+    public BoolValue UpdateConstantsInIntermediateNodes {
+      get { return UpdateConstantsInIntermediateNodesParameter.Value; }
+    }
+    public IntValue Generations {
+      get { return GenerationsParameter.ActualValue; }
+    }
+    public ResultCollection Results {
+      get { return ResultsParameter.ActualValue; }
+    }
+    public bool EnabledByDefault { get { return true; } }
+    #endregion
+
+
+    [StorableConstructor]
+    private GeneticOperatorImprovementAnalyzer(bool deserializing) : base(deserializing) { }
+    private GeneticOperatorImprovementAnalyzer(GeneticOperatorImprovementAnalyzer original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new GeneticOperatorImprovementAnalyzer(this, cloner);
+    }
+    public GeneticOperatorImprovementAnalyzer() {
+      Parameters.Add(new ValueParameter<IntValue>(UpdateIntervalParameterName, "The interval in which the tree length analysis should be applied.", new IntValue(1)));
+      Parameters.Add(new ValueParameter<IntValue>(UpdateCounterParameterName, "The value which counts how many times the operator was called since the last update", new IntValue(0)));
+      Parameters.Add(new ValueLookupParameter<ResultCollection>(ResultsParameterName, "The results collection where the analysis values should be stored."));
+      Parameters.Add(new LookupParameter<IntValue>(GenerationsParameterName, "The number of generations so far"));
+      Parameters.Add(new ValueParameter<BoolValue>(UpdateConstantsInIntermediateNodesParameterName, "Controls whether or not the constant values of the intermediate nodes should be updated.", new BoolValue(false)));
+
+      UpdateCounterParameter.Hidden = true;
+      UpdateIntervalParameter.Hidden = true;
+    }
+
+    #region AfterDeserialization
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      if (!Parameters.ContainsKey(UpdateConstantsInIntermediateNodesParameterName))
+        Parameters.Add(new ValueParameter<BoolValue>(UpdateConstantsInIntermediateNodesParameterName, "Controls whether or not the constant values of the intermediate nodes should be updated."));
+    }
+    #endregion
+
+    #region IStatefulItem members
+    public override void InitializeState() {
+      base.InitializeState();
+      UpdateCounter.Value = 0;
+    }
+
+    public override void ClearState() {
+      base.ClearState();
+      UpdateCounter.Value = 0;
+    }
+    #endregion
+
+    public override IOperation Apply() {
+      UpdateCounter.Value++;
+      if (UpdateCounter.Value == UpdateInterval.Value) {
+        UpdateCounter.Value = 0;
+
+        if (!Results.ContainsKey(PopulationGraphParameterName)) return base.Apply();
+
+        var graph = (SymbolicExpressionTreeGenealogyGraph)Results[PopulationGraphParameterName].Value;
+
+        var nodes = graph.Nodes.Where(n => n.Rank == Generations.Value); // get the nodes in the last generation and their parents
+
+        var crossoverImprovements = new List<double>();
+        var mutationImprovements = new List<double>();
+
+        // in case we need to use it
+        var evaluator = new SymbolicRegressionConstantOptimizationEvaluator();
+        evaluator.EvaluationPartitionParameter.ActualName = "FitnessCalculationPartition";
+
+        foreach (var node in nodes.Where(n => n.InEdges != null).OrderByDescending(n => n.InEdges.Count)) {
+          double parentsQuality = node.InEdges.Select(e => e.Source).Max(v => ((SymbolicExpressionGenealogyGraphNode)v).Quality);
+          double childQuality = node.Quality;
+          double improvement = childQuality - parentsQuality;
+          if (double.IsNaN(improvement) || double.IsInfinity(improvement) || parentsQuality.IsAlmost(0.0)) improvement = 0;
+          switch (node.InEdges.Count) {
+            case 2: // crossover
+              crossoverImprovements.Add(improvement);
+              break;
+            case 1: // mutation
+              // determine if we should update the quality
+              mutationImprovements.Add(improvement);
+              break;
+          }
+        }
+
+        if (!Results.ContainsKey(GeneticOperatorsAverageImprovementResultName)) {
+          Results.Add(new Result(GeneticOperatorsAverageImprovementResultName, new DataTable()));
+        }
+        var table = Results[GeneticOperatorsAverageImprovementResultName].Value as DataTable;
+
+        double cxAvgImprovement = 0.0;
+        double cxMaxImprovement = 0.0;
+        if (crossoverImprovements.Count > 0) {
+          cxAvgImprovement = crossoverImprovements.Average();
+          cxMaxImprovement = crossoverImprovements.Max();
+        }
+        double mutAvgImprovement = 0.0;
+        double mutMaxImprovement = 0.0;
+        if (mutationImprovements.Count > 0) {
+          mutAvgImprovement = mutationImprovements.Average();
+          mutMaxImprovement = mutationImprovements.Max();
+        }
+
+
+        if (!table.Rows.ContainsKey("Average crossover improvement")) {
+          table.Rows.Add(new DataRow("Average crossover improvement") { VisualProperties = { StartIndexZero = true } });
+        }
+        table.Rows["Average crossover improvement"].Values.Add(cxAvgImprovement);
+
+        if (!table.Rows.ContainsKey("Average mutation improvement")) {
+          table.Rows.Add(new DataRow("Average mutation improvement") { VisualProperties = { StartIndexZero = true } });
+        }
+        table.Rows["Average mutation improvement"].Values.Add(mutAvgImprovement);
+
+        if (!table.Rows.ContainsKey("Best crossover improvement")) {
+          table.Rows.Add(new DataRow("Best crossover improvement") { VisualProperties = { StartIndexZero = true } });
+        }
+        table.Rows["Best crossover improvement"].Values.Add(cxMaxImprovement);
+
+        if (!table.Rows.ContainsKey("Best mutation improvement")) {
+          table.Rows.Add(new DataRow("Best mutation improvement") { VisualProperties = { StartIndexZero = true } });
+        }
+        table.Rows["Best mutation improvement"].Values.Add(mutMaxImprovement);
+
+        if (!table.Rows.ContainsKey("Average improvement")) {
+          table.Rows.Add(new DataRow("Average improvement") { VisualProperties = { StartIndexZero = true } });
+        }
+        table.Rows["Average improvement"].Values.Add((cxAvgImprovement + mutAvgImprovement) / 2);
+
+        if (!table.Rows.ContainsKey("Best improvement")) {
+          table.Rows.Add(new DataRow("Best improvement") { VisualProperties = { StartIndexZero = true } });
+        }
+        table.Rows["Best improvement"].Values.Add(Math.Max(cxMaxImprovement, mutMaxImprovement));
+      }
+      return base.Apply();
+    }
+  }
+}
Index: anches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/Analyzers/GeneticOperatorsAverageImprovementAnalyzer.cs
===================================================================
--- /branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/Analyzers/GeneticOperatorsAverageImprovementAnalyzer.cs	(revision 9237)
+++ 	(revision )
@@ -1,175 +1,0 @@
-﻿using System;
-using System.Collections.Generic;
-using System.Linq;
-using HeuristicLab.Analysis;
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Data;
-using HeuristicLab.Operators;
-using HeuristicLab.Optimization;
-using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-
-namespace HeuristicLab.EvolutionaryTracking {
-  /// An analyzer that looks at individual lineages in the genealogy graph
-  /// </summary>
-  [Item("GeneticOperatorsAverageImprovementAnalyzer", "An operator that records the average success of genetic operators such as crossover and mutation.")]
-  [StorableClass]
-  class GeneticOperatorsAverageImprovementAnalyzer : SingleSuccessorOperator, IAnalyzer {
-    #region Parameter names
-    private const string UpdateIntervalParameterName = "UpdateInterval";
-    private const string UpdateCounterParameterName = "UpdateCounter";
-    private const string ResultsParameterName = "Results";
-    private const string GenerationsParameterName = "Generations";
-    private const string PopulationGraphParameterName = "PopulationGraph";
-    private const string GeneticOperatorsAverageImprovementResultName = "GeneticOperatorsAverageImprovement";
-    #endregion
-
-    #region Parameter properties
-    public ValueParameter<IntValue> UpdateIntervalParameter {
-      get { return (ValueParameter<IntValue>)Parameters[UpdateIntervalParameterName]; }
-    }
-    public ValueParameter<IntValue> UpdateCounterParameter {
-      get { return (ValueParameter<IntValue>)Parameters[UpdateCounterParameterName]; }
-    }
-    public LookupParameter<ResultCollection> ResultsParameter {
-      get { return (LookupParameter<ResultCollection>)Parameters[ResultsParameterName]; }
-    }
-    public LookupParameter<IntValue> GenerationsParameter {
-      get { return (LookupParameter<IntValue>)Parameters[GenerationsParameterName]; }
-    }
-    #endregion
-
-    #region Properties
-    public IntValue UpdateInterval {
-      get { return UpdateIntervalParameter.Value; }
-    }
-    public IntValue UpdateCounter {
-      get { return UpdateCounterParameter.Value; }
-    }
-    public IntValue Generations {
-      get { return GenerationsParameter.ActualValue; }
-    }
-    public ResultCollection Results {
-      get { return ResultsParameter.ActualValue; }
-    }
-    public bool EnabledByDefault { get { return true; } }
-    #endregion
-
-
-    [StorableConstructor]
-    private GeneticOperatorsAverageImprovementAnalyzer(bool deserializing) : base(deserializing) { }
-    private GeneticOperatorsAverageImprovementAnalyzer(GeneticOperatorsAverageImprovementAnalyzer original, Cloner cloner) : base(original, cloner) { }
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new GeneticOperatorsAverageImprovementAnalyzer(this, cloner);
-    }
-    public GeneticOperatorsAverageImprovementAnalyzer() {
-      Parameters.Add(new ValueParameter<IntValue>(UpdateIntervalParameterName, "The interval in which the tree length analysis should be applied.", new IntValue(1)));
-      Parameters.Add(new ValueParameter<IntValue>(UpdateCounterParameterName, "The value which counts how many times the operator was called since the last update", new IntValue(0)));
-      Parameters.Add(new ValueLookupParameter<ResultCollection>(ResultsParameterName, "The results collection where the analysis values should be stored."));
-      Parameters.Add(new LookupParameter<IntValue>(GenerationsParameterName, "The number of generations so far"));
-
-      UpdateCounterParameter.Hidden = true;
-      UpdateIntervalParameter.Hidden = true;
-    }
-
-    #region AfterDeserialization
-    [StorableHook(HookType.AfterDeserialization)]
-    private void AfterDeserialization() {
-    }
-    #endregion
-
-    #region IStatefulItem members
-    public override void InitializeState() {
-      base.InitializeState();
-      UpdateCounter.Value = 0;
-    }
-
-    public override void ClearState() {
-      base.ClearState();
-      UpdateCounter.Value = 0;
-    }
-    #endregion
-
-    public override IOperation Apply() {
-      UpdateCounter.Value++;
-      if (UpdateCounter.Value == UpdateInterval.Value) {
-        UpdateCounter.Value = 0;
-
-        if (!Results.ContainsKey(PopulationGraphParameterName)) return base.Apply();
-
-        var graph = (SymbolicExpressionTreeGenealogyGraph)Results[PopulationGraphParameterName].Value;
-
-        var nodes = graph.Nodes.Where(n => n.Rank == Generations.Value); // get the nodes in the last generation and their parents
-
-        var crossoverImprovements = new List<double>();
-        var mutationImprovements = new List<double>();
-
-        foreach (var node in nodes) {
-          if (node.InEdges == null) continue; // it means the corresponding individual did not reproduce
-          var parentsQuality = node.InEdges.Select(e => e.Source).Max(v => ((SymbolicExpressionGenealogyGraphNode)v).Quality);
-          var childQuality = node.Quality;
-          var improvement = childQuality / parentsQuality;
-          if (double.IsNaN(improvement) || double.IsInfinity(improvement) || parentsQuality.IsAlmost(0.0)) improvement = 0;
-          switch (node.InEdges.Count) {
-            case 2: // crossover
-              crossoverImprovements.Add(improvement);
-              break;
-            case 1: // mutation
-              mutationImprovements.Add(improvement);
-              break;
-          }
-        }
-
-        if (!Results.ContainsKey(GeneticOperatorsAverageImprovementResultName)) {
-          Results.Add(new Result(GeneticOperatorsAverageImprovementResultName, new DataTable()));
-        }
-        var table = Results[GeneticOperatorsAverageImprovementResultName].Value as DataTable;
-
-        double cxAvgImprovement = 0.0;
-        double cxMaxImprovement = 0.0;
-        if (crossoverImprovements.Count > 0) {
-          cxAvgImprovement = crossoverImprovements.Average();
-          cxMaxImprovement = crossoverImprovements.Max();
-        }
-        double mutAvgImprovement = 0.0;
-        double mutMaxImprovement = 0.0;
-        if (mutationImprovements.Count > 0) {
-          mutAvgImprovement = mutationImprovements.Average();
-          mutMaxImprovement = mutationImprovements.Max();
-        }
-
-        if (!table.Rows.ContainsKey("Average crossover improvement")) {
-          table.Rows.Add(new DataRow("Average crossover improvement") { VisualProperties = { StartIndexZero = true } });
-        }
-        table.Rows["Average crossover improvement"].Values.Add(cxAvgImprovement);
-
-        if (!table.Rows.ContainsKey("Average mutation improvement")) {
-          table.Rows.Add(new DataRow("Average mutation improvement") { VisualProperties = { StartIndexZero = true } });
-        }
-        table.Rows["Average mutation improvement"].Values.Add(mutAvgImprovement);
-
-        if (!table.Rows.ContainsKey("Best crossover improvement")) {
-          table.Rows.Add(new DataRow("Best crossover improvement") { VisualProperties = { StartIndexZero = true } });
-        }
-        table.Rows["Best crossover improvement"].Values.Add(cxMaxImprovement);
-
-        if (!table.Rows.ContainsKey("Best mutation improvement")) {
-          table.Rows.Add(new DataRow("Best mutation improvement") { VisualProperties = { StartIndexZero = true } });
-        }
-        table.Rows["Best mutation improvement"].Values.Add(mutMaxImprovement);
-
-        if (!table.Rows.ContainsKey("Average improvement")) {
-          table.Rows.Add(new DataRow("Average improvement") { VisualProperties = { StartIndexZero = true } });
-        }
-        table.Rows["Average improvement"].Values.Add((cxAvgImprovement + mutAvgImprovement) / 2);
-
-        if (!table.Rows.ContainsKey("Best improvement")) {
-          table.Rows.Add(new DataRow("Best improvement") { VisualProperties = { StartIndexZero = true } });
-        }
-        table.Rows["Best improvement"].Values.Add(Math.Max(cxMaxImprovement, mutMaxImprovement));
-      }
-      return base.Apply();
-    }
-  }
-}
Index: anches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/Analyzers/SymbolicExpressionTreeEvolvabilityAnalyzer.cs
===================================================================
--- /branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/Analyzers/SymbolicExpressionTreeEvolvabilityAnalyzer.cs	(revision 9237)
+++ 	(revision )
@@ -1,176 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System.Linq;
-using HeuristicLab.Analysis;
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Data;
-using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
-using HeuristicLab.Operators;
-using HeuristicLab.Optimization;
-using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-
-// type definitions for ease of use
-
-namespace HeuristicLab.EvolutionaryTracking {
-  /// <summary>
-  /// Population diversity analyzer
-  /// </summary>
-  [Item("SymbolicExpressionTreeEvolvabilityAnalyzer", "An operator that measures relative improvements obtained by genetic operators.")]
-  [StorableClass]
-  public sealed class SymbolicExpressionTreeEvolvabilityAnalyzer : SingleSuccessorOperator, IAnalyzer {
-    #region Parameter names
-    private const string SymbolicExpressionTreeParameterName = "SymbolicExpressionTree";
-    private const string UpdateIntervalParameterName = "UpdateInterval";
-    private const string UpdateCounterParameterName = "UpdateCounter";
-    private const string ResultsParameterName = "Results";
-    private const string PopulationGraphParameterName = "PopulationGraph";
-    private const string PopulationSizeParameterName = "PopulationSize";
-    private const string ElitesParameterName = "Elites";
-    #endregion
-
-    #region Parameter properties
-    public ValueParameter<IntValue> UpdateIntervalParameter {
-      get { return (ValueParameter<IntValue>)Parameters[UpdateIntervalParameterName]; }
-    }
-    public ValueParameter<IntValue> UpdateCounterParameter {
-      get { return (ValueParameter<IntValue>)Parameters[UpdateCounterParameterName]; }
-    }
-    public LookupParameter<ResultCollection> ResultsParameter {
-      get { return (LookupParameter<ResultCollection>)Parameters[ResultsParameterName]; }
-    }
-    public IScopeTreeLookupParameter<ISymbolicExpressionTree> SymbolicExpressionTreeParameter {
-      get { return (IScopeTreeLookupParameter<ISymbolicExpressionTree>)Parameters[SymbolicExpressionTreeParameterName]; }
-    }
-    public LookupParameter<IntValue> ElitesParameter {
-      get { return (LookupParameter<IntValue>)Parameters[ElitesParameterName]; }
-    }
-    public LookupParameter<IntValue> PopulationSizeParameter {
-      get { return (LookupParameter<IntValue>)Parameters[PopulationSizeParameterName]; }
-    }
-    #endregion
-
-    #region Parameters
-    public IntValue UpdateInterval { get { return UpdateIntervalParameter.Value; } }
-    public IntValue UpdateCounter { get { return UpdateCounterParameter.Value; } }
-    public ResultCollection Results { get { return ResultsParameter.ActualValue; } }
-    public IntValue PopulationSize { get { return PopulationSizeParameter.ActualValue; } }
-    public IntValue Elites { get { return ElitesParameter.ActualValue; } }
-    #endregion
-
-    [StorableConstructor]
-    private SymbolicExpressionTreeEvolvabilityAnalyzer(bool deserializing) : base(deserializing) { }
-    private SymbolicExpressionTreeEvolvabilityAnalyzer(SymbolicExpressionTreeEvolvabilityAnalyzer original, Cloner cloner) : base(original, cloner) { }
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new SymbolicExpressionTreeEvolvabilityAnalyzer(this, cloner);
-    }
-    public SymbolicExpressionTreeEvolvabilityAnalyzer() {
-      // add parameters
-      Parameters.Add(new ScopeTreeLookupParameter<ISymbolicExpressionTree>(SymbolicExpressionTreeParameterName, "The symbolic expression trees to analyze."));
-      Parameters.Add(new ValueParameter<IntValue>(UpdateIntervalParameterName, "The interval in which the tree length analysis should be applied.", new IntValue(1)));
-      Parameters.Add(new ValueParameter<IntValue>(UpdateCounterParameterName, "The value which counts how many times the operator was called since the last update", new IntValue(0)));
-      Parameters.Add(new ValueLookupParameter<ResultCollection>(ResultsParameterName, "The results collection where the analysis values should be stored."));
-      Parameters.Add(new LookupParameter<IntValue>(PopulationSizeParameterName, "The population size."));
-      Parameters.Add(new LookupParameter<IntValue>(ElitesParameterName, "Number of elites in the population."));
-
-      UpdateCounterParameter.Hidden = true;
-      UpdateIntervalParameter.Hidden = true;
-    }
-    [StorableHook(HookType.AfterDeserialization)]
-    private void AfterDeserialization() { }
-
-    #region IStatefulItem members
-    public override void InitializeState() {
-      base.InitializeState();
-      UpdateCounter.Value = 0;
-    }
-
-    public override void ClearState() {
-      base.ClearState();
-      UpdateCounter.Value = 0;
-    }
-    #endregion
-
-    public override IOperation Apply() {
-      UpdateCounter.Value++;
-
-      if (UpdateCounter.Value == UpdateInterval.Value) {
-        UpdateCounter.Value = 0;
-
-        if (!Results.ContainsKey(PopulationGraphParameterName)) return base.Apply();
-        var graph = Results[PopulationGraphParameterName].Value as SymbolicExpressionTreeGenealogyGraph;
-        if (graph == null) return base.Apply();
-
-        if (graph.Nodes.Count < PopulationSize.Value) return base.Apply();
-
-        var trees = SymbolicExpressionTreeParameter.ActualValue.ToList();
-
-        var graphNodes = trees.Select(x => graph.GetGraphNodes(x).Last());
-
-        int count = 0;
-
-        foreach (var node in graphNodes) {
-          double parentQuality = 0.0;
-          if (node.InEdges == null) continue;
-          switch (node.InEdges.Count) {
-            case 2: // crossover
-              parentQuality = node.InEdges.Max(x => (x.Source as SymbolicExpressionGenealogyGraphNode).Quality);
-              break;
-            case 1: // mutation
-              parentQuality = (node.InEdges[0].Source as SymbolicExpressionGenealogyGraphNode).Quality;
-              break;
-          }
-
-          if (node.Quality > parentQuality) ++count;
-        }
-        double reproductiveSuccess = (double)count / (PopulationSize.Value - Elites.Value);
-
-        if (!Results.ContainsKey("RelativeReproductiveSuccess"))
-          Results.Add(new Result("RelativeReproductiveSuccess", new DataTable("Reproductive success")));
-
-        var relativeReproductiveSuccessTable = Results["RelativeReproductiveSuccess"].Value as DataTable;
-        if (relativeReproductiveSuccessTable == null) return base.Apply();
-        if (!relativeReproductiveSuccessTable.Rows.ContainsKey("Reproductive Success"))
-          relativeReproductiveSuccessTable.Rows.Add(new DataRow("Reproductive Success") { VisualProperties = { StartIndexZero = true } });
-        relativeReproductiveSuccessTable.Rows["Reproductive Success"].Values.Add(reproductiveSuccess);
-
-        if (!Results.ContainsKey("RelativeProportionOfLeafNodes"))
-          Results.Add(new Result("RelativeProportionOfLeafNodes", new DataTable("Proportion of leaf nodes")));
-        var relativeProportionOfLeafNodesTable = Results["RelativeProportionOfLeafNodes"].Value as DataTable;
-        if (!relativeProportionOfLeafNodesTable.Rows.ContainsKey("Percent of leaf nodes"))
-          relativeProportionOfLeafNodesTable.Rows.Add(new DataRow("Percent of leaf nodes") { VisualProperties = { StartIndexZero = true } });
-        if (!relativeProportionOfLeafNodesTable.Rows.ContainsKey("Average number of leafs"))
-          relativeProportionOfLeafNodesTable.Rows.Add(new DataRow("Average number of leafs") { VisualProperties = { StartIndexZero = true } });
-
-        double totalNodes = trees.Sum(x => x.Length);
-        double totalLeafs = trees.Sum(t => t.IterateNodesPostfix().Count(n => n.SubtreeCount == 0));
-
-        relativeProportionOfLeafNodesTable.Rows["Percent of leaf nodes"].Values.Add(totalLeafs / totalNodes);
-        relativeProportionOfLeafNodesTable.Rows["Average number of leafs"].Values.Add(totalLeafs / trees.Count);
-      }
-      return base.Apply();
-    }
-
-    public bool EnabledByDefault { get { return true; } }
-  }
-}
Index: anches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/Analyzers/SymbolicExpressionTreeFragmentLengthsAnalyzer.cs
===================================================================
--- /branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/Analyzers/SymbolicExpressionTreeFragmentLengthsAnalyzer.cs	(revision 9237)
+++ 	(revision )
@@ -1,153 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System.Collections.Generic;
-using System.Linq;
-using HeuristicLab.Analysis;
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
-using HeuristicLab.Optimization;
-using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-// type definitions for convenience
-using CloneMapType = HeuristicLab.Core.ItemDictionary<HeuristicLab.Core.IItem, HeuristicLab.Core.IItem>;
-using TraceMapType = HeuristicLab.Core.ItemDictionary<HeuristicLab.Core.IItem, HeuristicLab.Core.IItemList<HeuristicLab.Core.IItem>>;
-
-namespace HeuristicLab.EvolutionaryTracking {
-  /// <summary>
-  /// An operator that gathers information on tree fragments that get passed from one generation to the next via genetic operators
-  /// (Tracking of genetic variance and heredity)
-  /// </summary>
-  [Item("SymbolicExpressionTreeFragmentLengthAnalyzer", "An operator that provides statistics about fragment lengths")]
-  [StorableClass]
-  public sealed class SymbolicExpressionTreeFragmentLengthAnalyzer : SymbolicExpressionTreeFragmentsAnalyzer {
-    private const string FragmentLengthsParameterName = "Fragment Lengths";
-    // impact values calculator
-    public ILookupParameter<DataTable> FragmentLengthsParameter { get { return (ILookupParameter<DataTable>)Parameters[FragmentLengthsParameterName]; } }
-    public DataTable FragmentLengths {
-      get { return FragmentLengthsParameter.ActualValue; }
-      set { FragmentLengthsParameter.ActualValue = value; }
-    }
-
-    [StorableConstructor]
-    private SymbolicExpressionTreeFragmentLengthAnalyzer(bool deserializing) : base(deserializing) { }
-    private SymbolicExpressionTreeFragmentLengthAnalyzer(SymbolicExpressionTreeFragmentLengthAnalyzer original, Cloner cloner) : base(original, cloner) { }
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new SymbolicExpressionTreeFragmentLengthAnalyzer(this, cloner);
-    }
-    public SymbolicExpressionTreeFragmentLengthAnalyzer()
-      : base() {
-      #region Add parameters
-      Parameters.Add(new LookupParameter<DataTable>(FragmentLengthsParameterName));
-      #endregion
-
-      UpdateCounterParameter.Hidden = true;
-      UpdateIntervalParameter.Hidden = true;
-
-
-    }
-    #region After deserialization code
-
-    [StorableHook(HookType.AfterDeserialization)]
-    private void AfterDeserialization() {
-    }
-
-    #endregion
-    #region IStatefulItem members
-    public override void InitializeState() {
-      base.InitializeState();
-      UpdateCounter.Value = 0;
-    }
-
-    public override void ClearState() {
-      base.ClearState();
-      UpdateCounter.Value = 0;
-    }
-    #endregion
-
-    public override IOperation Apply() {
-      UpdateCounter.Value++;
-      if (UpdateCounter.Value == UpdateInterval.Value) {
-        UpdateCounter.Value = 0; // reset counter
-        if (Generations.Value > 1) {
-          SecondaryTraceMap = SecondaryTraceMap ?? new TraceMapType();
-          SecondaryFragmentMap = SecondaryFragmentMap ?? new CloneMapType();
-          SecondaryCloneMap = SecondaryCloneMap ?? new CloneMapType();
-
-          InitializeParameters();
-          InitializeRows();
-
-          var parents = SecondaryTraceMap.Values.SelectMany(list => list.Cast<ISymbolicExpressionTree>()).ToList(); // parents of individuals at generation N-1
-          var offspring = SecondaryTraceMap.Keys.Cast<ISymbolicExpressionTree>().ToList(); // individuals at generation N-1
-          var fragments = SecondaryFragmentMap.Values.Cast<IFragment>().ToList();
-
-
-          // a hash of the offspring trees that got selected for reproduction at generation N
-          var selected = new HashSet<ISymbolicExpressionTree>(GlobalTraceMap.Values.SelectMany(list => list.Cast<ISymbolicExpressionTree>()));
-
-          var selectedOffspringFragments = SecondaryFragmentMap.Where(m => selected.Contains((ISymbolicExpressionTree)m.Key)).Select(m => m.Key).ToList();
-
-          var selectedOffspring = offspring.Where(selected.Contains).ToList();
-          var selectedOffspringParents = selectedOffspring.SelectMany(x => SecondaryTraceMap[x].Cast<ISymbolicExpressionTree>()).ToList();
-
-          var rows = FragmentLengths.Rows;
-
-          double avgParentsLength = parents.Count > 0 ? parents.Average(p => p.Length) : 0;
-          double avgGoodParentsLength = selectedOffspringParents.Count > 0 ? selectedOffspringParents.Average(p => p.Length) : 0;
-          rows["Parent lengths (all)"].Values.Add(avgParentsLength);
-          rows["Parent lengths (good)"].Values.Add(avgGoodParentsLength);
-          double avgOffspringLength = offspring.Count > 0 ? offspring.Average(o => o.Length) : 0;
-          double avgGoodOffspringLength = selectedOffspring.Count > 0 ? selectedOffspring.Average(o => o.Length) : 0;
-          rows["Offspring lengths (good)"].Values.Add(avgOffspringLength);
-          rows["Offspring lengths (all)"].Values.Add(avgGoodOffspringLength);
-          double avgFragmentLength = fragments.Count > 0 ? fragments.Average(f => f.Length) : 0;
-          double avgGoodFragmentLength = selectedOffspringFragments.Count > 0 ? fragments.Average(f => f.Length) : 0;
-          rows["Fragment lengths (good)"].Values.Add(avgGoodFragmentLength);
-          rows["Fragment lengths (all)"].Values.Add(avgFragmentLength);
-        }
-      }
-
-      return base.Apply();
-    }
-
-    protected override void InitializeParameters() {
-      var results = ResultsParameter.ActualValue;
-      if (!results.ContainsKey("Fragment Lengths")) {
-        FragmentLengths = FragmentLengths ?? new DataTable("Fragment Lengths") { VisualProperties = { YAxisTitle = "Fragment length" } };
-        results.Add(new Result("Fragment Lengths", FragmentLengths));
-      }
-      base.InitializeParameters();
-    }
-
-    private void InitializeRows() {
-      string[] rowNames =
-        {
-          "Parent lengths (good)", "Parent lengths (all)",
-          "Offspring lengths (good)", "Offspring lengths (all)",
-          "Fragment lengths (good)", "Fragment lengths (all)"
-        };
-      foreach (var rowName in rowNames.Where(rowName => !FragmentLengths.Rows.ContainsKey(rowName))) {
-        FragmentLengths.Rows.Add(new DataRow(rowName) { VisualProperties = { StartIndexZero = true } });
-      }
-    }
-  } //SymbolicExpressionTreeFragmentLengthAnalyzer
-}
Index: anches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/Analyzers/SymbolicExpressionTreeFragmentsAnalyzer.cs
===================================================================
--- /branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/Analyzers/SymbolicExpressionTreeFragmentsAnalyzer.cs	(revision 9237)
+++ 	(revision )
@@ -1,314 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System.Collections.Generic;
-using System.Linq;
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Data;
-using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
-using HeuristicLab.Operators;
-using HeuristicLab.Optimization;
-using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-using HeuristicLab.Problems.DataAnalysis;
-using HeuristicLab.Problems.DataAnalysis.Symbolic;
-// type definitions for convenience
-using HeuristicLab.Problems.DataAnalysis.Symbolic.Regression;
-using CloneMapType = HeuristicLab.Core.ItemDictionary<HeuristicLab.Core.IItem, HeuristicLab.Core.IItem>;
-using TraceMapType = HeuristicLab.Core.ItemDictionary<HeuristicLab.Core.IItem, HeuristicLab.Core.IItemList<HeuristicLab.Core.IItem>>;
-
-namespace HeuristicLab.EvolutionaryTracking {
-  /// <summary>
-  /// An operator that gathers information on tree fragments that get passed from one generation to the next via genetic operators
-  /// (Tracking of genetic variance and heredity)
-  /// </summary>
-  [Item("SymbolicExpressionTreeFragmentsAnalyzer", "An operator that provides statistics about crossover fragments")]
-  [StorableClass]
-  public abstract class SymbolicExpressionTreeFragmentsAnalyzer : SingleSuccessorOperator, IAnalyzer {
-    #region Parameter names
-    protected const string UpdateIntervalParameterName = "UpdateInterval";
-    protected const string UpdateCounterParameterName = "UpdateCounter";
-    protected const string ResultsParameterName = "Results";
-    protected const string SecondaryTraceMapParameterName = "SecondaryTraceMap";
-    protected const string SecondaryFragmentMapParameterName = "SecondaryFragmentMap";
-    protected const string SecondaryCloneMapParameterName = "SecondaryCloneMap";
-    protected const string GlobalTraceMapParameterName = "GlobalTraceMap";
-    protected const string GlobalTraceMapParameterDescription = "Global map of trees and their parents.";
-    protected const string GlobalCloneMapParameterName = "GlobalCloneMap";
-    protected const string GlobalCloneMapParameterDescription = "Global map of trees and their clones";
-    protected const string GlobalFragmentMapParameterName = "GlobalFragmentMap";
-    protected const string GlobalFragmentMapParameterDescription = "Global map of trees and their respective fragments.";
-    protected const string GenerationsParameterName = "Generations";
-    protected const string SymbolicExpressionInterpreterParameterName = "SymbolicExpressionTreeInterpreter";
-    protected const string SymbolicRegressionProblemDataParameterName = "ProblemData";
-    #endregion
-
-    // impact values calculator
-    private readonly SymbolicRegressionSolutionImpactValuesCalculator calculator = new SymbolicRegressionSolutionImpactValuesCalculator();
-
-    #region Parameter properties
-    public ValueParameter<IntValue> UpdateIntervalParameter {
-      get { return (ValueParameter<IntValue>)Parameters[UpdateIntervalParameterName]; }
-    }
-    public ValueParameter<IntValue> UpdateCounterParameter {
-      get { return (ValueParameter<IntValue>)Parameters[UpdateCounterParameterName]; }
-    }
-    public LookupParameter<ResultCollection> ResultsParameter {
-      get { return (LookupParameter<ResultCollection>)Parameters[ResultsParameterName]; }
-    }
-    public LookupParameter<IntValue> GenerationsParameter {
-      get { return (LookupParameter<IntValue>)Parameters[GenerationsParameterName]; }
-    }
-    // tracking structures
-    public LookupParameter<TraceMapType> GlobalTraceMapParameter {
-      get { return (LookupParameter<TraceMapType>)Parameters[GlobalTraceMapParameterName]; }
-    }
-    public LookupParameter<CloneMapType> GlobalCloneMapParameter {
-      get { return (LookupParameter<CloneMapType>)Parameters[GlobalCloneMapParameterName]; }
-    }
-    public LookupParameter<CloneMapType> GlobalFragmentMapParameter {
-      get { return (LookupParameter<CloneMapType>)Parameters[GlobalFragmentMapParameterName]; }
-    }
-    // auxiliary structures for tracking fragments and individuals from the previous generation
-    // (this is needed because tracking is done in connection to the current generation, i.e., for 
-    // counting "successful" offspring and fragments
-    public LookupParameter<TraceMapType> SecondaryTraceMapParameter {
-      get { return (LookupParameter<TraceMapType>)Parameters[SecondaryTraceMapParameterName]; }
-    }
-    public LookupParameter<CloneMapType> SecondaryFragmentMapParameter {
-      get { return (LookupParameter<CloneMapType>)Parameters[SecondaryFragmentMapParameterName]; }
-    }
-    public LookupParameter<CloneMapType> SecondaryCloneMapParameter {
-      get { return (LookupParameter<CloneMapType>)Parameters[SecondaryCloneMapParameterName]; }
-    }
-    // problem data, interpreter and evaluator
-    public LookupParameter<SymbolicDataAnalysisExpressionTreeInterpreter> SymbolicExpressionInterpreterParameter {
-      get { return (LookupParameter<SymbolicDataAnalysisExpressionTreeInterpreter>)Parameters[SymbolicExpressionInterpreterParameterName]; }
-    }
-    public LookupParameter<RegressionProblemData> SymbolicRegressionProblemDataParameter {
-      get { return (LookupParameter<RegressionProblemData>)Parameters[SymbolicRegressionProblemDataParameterName]; }
-    }
-    #endregion
-
-    #region Parameters
-    public bool EnabledByDefault {
-      get { return true; }
-    }
-    public IntValue UpdateInterval {
-      get { return UpdateIntervalParameter.Value; }
-    }
-    public IntValue UpdateCounter {
-      get { return UpdateCounterParameter.Value; }
-    }
-    public ResultCollection Results {
-      get { return ResultsParameter.ActualValue; }
-    }
-    public CloneMapType GlobalCloneMap {
-      get { return GlobalCloneMapParameter.ActualValue; }
-    }
-    public TraceMapType GlobalTraceMap {
-      get { return GlobalTraceMapParameter.ActualValue; }
-    }
-    public TraceMapType SecondaryTraceMap {
-      get { return SecondaryTraceMapParameter.ActualValue; }
-      set { SecondaryTraceMapParameter.ActualValue = value; }
-    }
-    public CloneMapType SecondaryFragmentMap {
-      get { return SecondaryFragmentMapParameter.ActualValue; }
-      set { SecondaryFragmentMapParameter.ActualValue = value; }
-    }
-    public CloneMapType SecondaryCloneMap {
-      get { return SecondaryCloneMapParameter.ActualValue; }
-      set { SecondaryCloneMapParameter.ActualValue = value; }
-    }
-    public CloneMapType GlobalFragmentMap {
-      get { return GlobalFragmentMapParameter.ActualValue; }
-    }
-    public IntValue Generations {
-      get { return GenerationsParameter.ActualValue; }
-    }
-    public SymbolicDataAnalysisExpressionTreeInterpreter SymbolicExpressionInterpreter {
-      get { return SymbolicExpressionInterpreterParameter.ActualValue; }
-    }
-    public RegressionProblemData SymbolicRegressionProblemData {
-      get { return SymbolicRegressionProblemDataParameter.ActualValue; }
-    }
-    #endregion
-
-    [StorableConstructor]
-    protected SymbolicExpressionTreeFragmentsAnalyzer(bool deserializing) : base(deserializing) { }
-
-    protected SymbolicExpressionTreeFragmentsAnalyzer(SymbolicExpressionTreeFragmentsAnalyzer original, Cloner cloner) : base(original, cloner) { }
-
-    protected SymbolicExpressionTreeFragmentsAnalyzer()
-      : base() {
-      #region Add parameters
-      // analyzer update counter and update interval
-      Parameters.Add(new ValueParameter<IntValue>(UpdateIntervalParameterName, "The interval in which the tree length analysis should be applied.", new IntValue(1)));
-      Parameters.Add(new ValueParameter<IntValue>(UpdateCounterParameterName, "The value which counts how many times the operator was called since the last update", new IntValue(0)));
-      // tracking
-      Parameters.Add(new LookupParameter<TraceMapType>(GlobalTraceMapParameterName, GlobalTraceMapParameterDescription));
-      Parameters.Add(new LookupParameter<CloneMapType>(GlobalCloneMapParameterName, GlobalCloneMapParameterDescription));
-      Parameters.Add(new LookupParameter<CloneMapType>(GlobalFragmentMapParameterName, GlobalFragmentMapParameterDescription));
-      // secondary tracking 
-      Parameters.Add(new LookupParameter<TraceMapType>(SecondaryTraceMapParameterName, GlobalTraceMapParameterDescription));
-      Parameters.Add(new LookupParameter<CloneMapType>(SecondaryCloneMapParameterName, GlobalCloneMapParameterDescription));
-      Parameters.Add(new LookupParameter<CloneMapType>(SecondaryFragmentMapParameterName, GlobalFragmentMapParameterDescription));
-      // impact calculation
-      Parameters.Add(new LookupParameter<SymbolicDataAnalysisExpressionTreeInterpreter>(SymbolicExpressionInterpreterParameterName, "Interpreter for symbolic expression trees"));
-      Parameters.Add(new LookupParameter<RegressionProblemData>(SymbolicRegressionProblemDataParameterName, "The symbolic data analysis problem."));
-      // fragment statistics parameters
-      Parameters.Add(new ValueLookupParameter<ResultCollection>(ResultsParameterName, "The results collection where the analysis values should be stored."));
-      Parameters.Add(new LookupParameter<IntValue>(GenerationsParameterName, "The number of generations so far."));
-      #endregion
-
-      UpdateCounterParameter.Hidden = true;
-      UpdateIntervalParameter.Hidden = true;
-
-    }
-    #region After deserialization code
-    [StorableHook(HookType.AfterDeserialization)]
-    private void AfterDeserialization() {
-      // check if all the parameters are present and accounted for 
-      if (!Parameters.ContainsKey(UpdateIntervalParameterName)) {
-        Parameters.Add(new ValueParameter<IntValue>(UpdateIntervalParameterName, "The interval in which the tree length analysis should be applied.", new IntValue(1)));
-      }
-      if (!Parameters.ContainsKey(UpdateCounterParameterName)) {
-        Parameters.Add(new ValueParameter<IntValue>(UpdateCounterParameterName, "The value which counts how many times the operator was called since the last update", new IntValue(0)));
-        UpdateCounterParameter.Hidden = true;
-      }
-    }
-    #endregion
-    #region IStatefulItem members
-    public override void InitializeState() {
-      base.InitializeState();
-      UpdateCounter.Value = 0;
-    }
-
-    public override void ClearState() {
-      base.ClearState();
-      UpdateCounter.Value = 0;
-    }
-    #endregion
-
-    /* A small description of the way this analyzer works
-     * 
-     * We keep 3 maps in the global scope: the GlobalTraceMap, the GlobalFragmentMap and the GlobalCloneMap that are updated on each step: selection, crossover, mutation
-     * These maps provide information about the children, parents and transferred fragments as follows:
-     * 
-     * 1) GlobalCloneMap
-     *    This data structure provides the basis for tracking. In the selection step, every selected individual gets cloned and transferred into the recombination pool.
-     *    The GlobalCloneMap keeps track of clones by mapping them to the original individuals. This is an essential step for building the genealogy graph. Using this
-     *    structure we can find out how many times each individual was selected. 
-     *    The GlobalCloneMap consists of Key-Value pairs Clone->Original
-     *
-     * 2) GlobalTraceMap
-     *    Keeps information in the form of key-value pairs Child->{Parents}, where {Parents} is a set consisting of 
-     *      - one parent individual (in the case of mutation), by language abuse we say that the individual that mutation acted on is the parent,
-     *        and the resulting individual is the child
-     *      - two parent individuals (in the case of crossover), named Parent0 and Parent1. Parent0 is the individual that crossover acts on by replacing 
-     *        one of its subtrees with a compatible subtree, randomly selected from Parent1
-     *
-     *    CROSSOVER
-     *        Parent0     Parent1                                                                    {Parents}
-     *           \           /                                                                           ^
-     *            \       fragment (inserted from Parent1 into Parent0 to create the Child)              ^    [Mapping provided by the GlobalTraceMap]
-     *             \       /                                                                             ^
-     *              \     /                                                                              ^
-     *               Child                                                                             Child
-     *               
-     *    MUTATION
-     *        Parent0
-     *           |
-     *           |    [mutation acts on a random node/subtree in the 'parent' individual
-     *           |
-     *         Child
-     *         
-     *    Since crossover and mutation act on individuals in the recombination pool (which in fact are clones of individuals from the previous generation), the GlobalTraceMap
-     *    is populated with values given by the mappings in the GlobalCloneMap, so that the original parent for each child is known.
-     *    
-     *  3) GlobalFragmentMap
-     *     Keeps information in the form of Key-Value pairs about an individual and its respective fragment 
-     *     (ie., the subtree received via crossover or created/altered by mutation)
-     * */
-
-    public override IOperation Apply() {
-      // save the current generation so it can be compared to the following one, next time the analyzer is applied
-      SecondaryTraceMap = SecondaryTraceMap ?? new TraceMapType();
-      SecondaryCloneMap = SecondaryCloneMap ?? new CloneMapType();
-      SecondaryFragmentMap = SecondaryFragmentMap ?? new CloneMapType();
-
-      SecondaryTraceMap.Clear();
-      if (GlobalTraceMap != null)
-        foreach (var m in GlobalTraceMap)
-          SecondaryTraceMap.Add(m.Key, m.Value);
-
-      SecondaryCloneMap.Clear();
-      if (GlobalCloneMap != null)
-        foreach (var m in GlobalCloneMap)
-          SecondaryCloneMap.Add(m.Key, m.Value);
-
-      SecondaryFragmentMap.Clear();
-      if (GlobalFragmentMap != null)
-        foreach (var m in GlobalFragmentMap)
-          SecondaryFragmentMap.Add(m.Key, m.Value);
-      return base.Apply();
-    }
-
-    protected virtual void InitializeParameters() {
-      #region Init parameters
-
-      #endregion
-    }
-
-    private static int VisitationLength(ISymbolicExpressionTree tree) {
-      return VisitationLength(tree.Root);
-    }
-
-    private static int VisitationLength(ISymbolicExpressionTreeNode node) {
-      return node.IterateNodesBreadth().Sum(n => n.GetLength());
-    }
-
-    #region Similarity computations
-    /// <summary>
-    /// Provide a measure of how similar the fragments that get passed by crossover from one generation to the next are. 
-    /// </summary>
-    /// <param name="fragments">The symbolic expression tree fragments</param>
-    /// <param name="mode">The similarity mode (0 - exact, 1 - high, 2 - relaxed)</param>
-    /// <returns>The average number of similar fragments</returns>
-    private static double CalculateSimilarity(IList<IFragment> fragments, SymbolicExpressionTreeNodeSimilarityComparer comparer) {
-      var visited = new bool[fragments.Count];
-      int groups = 0;
-      for (int i = 0; i != fragments.Count - 1; ++i) {
-        if (visited[i]) continue;
-        for (int j = i + 1; j != fragments.Count; ++j) {
-          if (visited[j]) continue;
-          if (fragments[i].Root.IsSimilarTo(fragments[j].Root, comparer))
-            visited[j] = true;
-        }
-        ++groups;
-      }
-      return (double)fragments.Count / groups;
-    }
-    #endregion
-  } //SymbolicExpressionTreeFragmentsAnalyzer
-}
Index: /branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/Analyzers/SymbolicExpressionTreeFrequentPatternsAnalyzer.cs
===================================================================
--- /branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/Analyzers/SymbolicExpressionTreeFrequentPatternsAnalyzer.cs	(revision 9237)
+++ /branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/Analyzers/SymbolicExpressionTreeFrequentPatternsAnalyzer.cs	(revision 9238)
@@ -96,5 +96,4 @@
     }
     #endregion
-
     #region Properties
     public bool EnabledByDefault {
@@ -361,5 +360,5 @@
           // adjust weights according to the probability a child will find itself on a certain argument position
           for (int j = 0; j != possibleChildConnections.Count; ++j) {
-            var childSymbolNode = possibleChildConnections[j].Target as SymbolNode;
+            var childSymbolNode = (SymbolNode)possibleChildConnections[j].Target;
             double sumPos = childSymbolNode.Positions.Sum(x => x.Value);
             int v; childSymbolNode.Positions.TryGetValue(i, out v);
Index: /branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/Analyzers/SymbolicExpressionTreePopulationDiversityAnalyzer.cs
===================================================================
--- /branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/Analyzers/SymbolicExpressionTreePopulationDiversityAnalyzer.cs	(revision 9237)
+++ /branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/Analyzers/SymbolicExpressionTreePopulationDiversityAnalyzer.cs	(revision 9238)
@@ -30,7 +30,8 @@
 using HeuristicLab.Parameters;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.DataAnalysis.Symbolic;
 
 // type definitions for ease of use
-using HeuristicLab.Problems.DataAnalysis.Symbolic;
+using CloneMapType = HeuristicLab.Core.ItemDictionary<HeuristicLab.Core.IItem, HeuristicLab.Core.IItem>;
 
 namespace HeuristicLab.EvolutionaryTracking {
@@ -46,7 +47,18 @@
     private const string UpdateCounterParameterName = "UpdateCounter";
     private const string ResultsParameterName = "Results";
-    #endregion
-
-    #region Parameter properties
+    private const string GenerationsParameterName = "Generations";
+    private const string StoreHistoryParameterName = "StoreHistory";
+    // comparer parameters
+    private const string MatchVariablesParameterName = "MatchVariableNames";
+    private const string MatchVariableWeightsParameterName = "MatchVariableWeights";
+    private const string MatchConstantValuesParameterName = "MatchConstantValues";
+    private const string SortSubtreesParameterName = "SortSubtrees";
+    // population graph
+    private const string PopulationGraphParameterName = "PopulationGraph";
+    // clone map
+    private const string GlobalCloneMapParameterName = "GlobalCloneMap";
+    #endregion
+
+    #region Parameters
     public ValueParameter<IntValue> UpdateIntervalParameter {
       get { return (ValueParameter<IntValue>)Parameters[UpdateIntervalParameterName]; }
@@ -58,10 +70,31 @@
       get { return (LookupParameter<ResultCollection>)Parameters[ResultsParameterName]; }
     }
+    public LookupParameter<IntValue> GenerationsParameter {
+      get { return (LookupParameter<IntValue>)Parameters[GenerationsParameterName]; }
+    }
+    public ValueParameter<BoolValue> StoreHistoryParameter {
+      get { return (ValueParameter<BoolValue>)Parameters[StoreHistoryParameterName]; }
+    }
     public IScopeTreeLookupParameter<ISymbolicExpressionTree> SymbolicExpressionTreeParameter {
       get { return (IScopeTreeLookupParameter<ISymbolicExpressionTree>)Parameters[SymbolicExpressionTreeParameterName]; }
     }
-    #endregion
-
-    #region Parameters
+    public ValueParameter<BoolValue> MatchVariableNamesParameter {
+      get { return (ValueParameter<BoolValue>)Parameters[MatchVariablesParameterName]; }
+    }
+    public ValueParameter<BoolValue> MatchVariableWeightsParameter {
+      get { return (ValueParameter<BoolValue>)Parameters[MatchVariableWeightsParameterName]; }
+    }
+    public ValueParameter<BoolValue> MatchConstantValuesParameter {
+      get { return (ValueParameter<BoolValue>)Parameters[MatchConstantValuesParameterName]; }
+    }
+    public ValueParameter<BoolValue> SortSubtreesParameter {
+      get { return (ValueParameter<BoolValue>)Parameters[SortSubtreesParameterName]; }
+    }
+    public LookupParameter<CloneMapType> GlobalCloneMapParameter {
+      get { return (LookupParameter<CloneMapType>)Parameters[GlobalCloneMapParameterName]; }
+    }
+    #endregion
+
+    #region Parameter properties
     public IntValue UpdateInterval {
       get { return UpdateIntervalParameter.Value; }
@@ -72,4 +105,13 @@
     public ResultCollection Results {
       get { return ResultsParameter.ActualValue; }
+    }
+    public CloneMapType GlobalCloneMap {
+      get { return GlobalCloneMapParameter.ActualValue; }
+    }
+    public IntValue Generations {
+      get { return GenerationsParameter.ActualValue; }
+    }
+    public BoolValue StoreHistory {
+      get { return StoreHistoryParameter.Value; }
     }
     #endregion
@@ -87,5 +129,11 @@
       Parameters.Add(new ValueParameter<IntValue>(UpdateCounterParameterName, "The value which counts how many times the operator was called since the last update", new IntValue(0)));
       Parameters.Add(new ValueLookupParameter<ResultCollection>(ResultsParameterName, "The results collection where the analysis values should be stored."));
-
+      Parameters.Add(new LookupParameter<IntValue>(GenerationsParameterName, "The number of generations so far."));
+      Parameters.Add(new ValueParameter<BoolValue>(MatchVariablesParameterName, "Specify if the symbolic expression tree comparer should match variable names."));
+      Parameters.Add(new ValueParameter<BoolValue>(MatchVariableWeightsParameterName, "Specify if the symbolic expression tree comparer should match variable weights."));
+      Parameters.Add(new ValueParameter<BoolValue>(MatchConstantValuesParameterName, "Specify if the symbolic expression tree comparer should match constant values."));
+      Parameters.Add(new ValueParameter<BoolValue>(SortSubtreesParameterName, "Specifies whether the subtrees of a tree should be sorted before comparison."));
+      Parameters.Add(new LookupParameter<CloneMapType>(GlobalCloneMapParameterName, "A global map keeping track of trees and their clones (made during selection)."));
+      Parameters.Add(new ValueParameter<BoolValue>(StoreHistoryParameterName, "True if the tree lengths history of the population should be stored.", new BoolValue(false)));
       UpdateCounterParameter.Hidden = true;
       UpdateIntervalParameter.Hidden = true;
@@ -106,4 +154,6 @@
     #endregion
 
+    public bool EnabledByDefault { get { return true; } }
+
     public override IOperation Apply() {
       UpdateCounter.Value++;
@@ -113,28 +163,82 @@
 
         var trees = SymbolicExpressionTreeParameter.ActualValue.ToList();
-        var canonicalSorter = new SymbolicExpressionTreeCanonicalSorter();
-        foreach (var t in trees) canonicalSorter.SortSubtrees(t);
-
-        var comparer = new SymbolicExpressionTreeNodeSimilarityComparer { MatchConstantValues = false, MatchVariableNames = false, MatchVariableWeights = false };
-
-        var distinct = 1.0 - trees.Select(x => x.Root).Distinct(comparer).Count() / (double)trees.Count;
-
-        var results = ResultsParameter.ActualValue;
-
-        if (!results.ContainsKey("PopulationDiversity"))
-          results.Add(new Result("PopulationDiversity", new DataTable("PopulationDiversity") { VisualProperties = { YAxisTitle = "Count" } }));
-        var populationDiversityTable = results["PopulationDiversity"].Value as DataTable;
-
-        if (populationDiversityTable == null) return base.Apply(); // should never happen
-
+        if (SortSubtreesParameter.Value.Value) {
+          var canonicalSorter = new SymbolicExpressionTreeCanonicalSorter();
+          foreach (var t in trees) canonicalSorter.SortSubtrees(t);
+        }
+
+        bool matchConstants = MatchConstantValuesParameter.Value.Value;
+        bool matchVarNames = MatchVariableNamesParameter.Value.Value;
+        bool matchVarWeights = MatchVariableWeightsParameter.Value.Value;
+
+        var comparer = new SymbolicExpressionTreeEqualityComparer {
+          SimilarityComparer = new SymbolicExpressionTreeNodeSimilarityComparer {
+            MatchConstantValues = matchConstants, MatchVariableNames = matchVarNames, MatchVariableWeights = matchVarWeights
+          }
+        };
+        ResultCollection results = ResultsParameter.ActualValue;
+        // population diversity
+        DataTable populationDiversityTable;
+        if (!results.ContainsKey("PopulationDiversity")) {
+          populationDiversityTable = new DataTable("PopulationDiversity") { VisualProperties = { YAxisTitle = "Diversity" } };
+          results.Add(new Result("PopulationDiversity", populationDiversityTable));
+        }
+        populationDiversityTable = (DataTable)results["PopulationDiversity"].Value;
         if (!populationDiversityTable.Rows.ContainsKey("Diversity"))
           populationDiversityTable.Rows.Add(new DataRow("Diversity") { VisualProperties = { StartIndexZero = true } });
-
+        double distinct = trees.Distinct(comparer).Count() / (double)trees.Count;
         populationDiversityTable.Rows["Diversity"].Values.Add(distinct);
+        // selection diversity
+        if (GlobalCloneMap == null) return base.Apply();
+
+        DataTable relativeSelectionCountsTable;
+        if (!results.ContainsKey("SelectedIndividuals")) {
+          relativeSelectionCountsTable = new DataTable("SelectedIndividuals") { VisualProperties = { YAxisTitle = "% Selected Individuals" } };
+          results.Add(new Result("SelectedIndividuals", relativeSelectionCountsTable));
+        }
+        relativeSelectionCountsTable = (DataTable)Results["SelectedIndividuals"].Value;
+        if (!relativeSelectionCountsTable.Rows.ContainsKey("SelectedIndividuals")) {
+          relativeSelectionCountsTable.Rows.Add(new DataRow("SelectedIndividuals") { VisualProperties = { StartIndexZero = true } });
+        }
+        double relativeSelectionCount = GlobalCloneMap.Values.Distinct().Count() / (double)trees.Count;
+        relativeSelectionCountsTable.Rows["SelectedIndividuals"].Values.Add(relativeSelectionCount);
+
+        // do a histogram of selection frequency for each individual in the population
+        DataTable selectionFrequenciesTable;
+        if (!results.ContainsKey("SelectionFrequencies")) {
+          selectionFrequenciesTable = new DataTable("Selection Frequencies") { VisualProperties = { YAxisTitle = "Selection Count" } };
+          results.Add(new Result("SelectionFrequencies", selectionFrequenciesTable));
+        }
+        selectionFrequenciesTable = (DataTable)results["SelectionFrequencies"].Value;
+        DataRow histoRow;
+        if (!selectionFrequenciesTable.Rows.ContainsKey("SelectionFrequencies")) {
+          histoRow = new DataRow("SelectionFrequencies") { VisualProperties = { StartIndexZero = true } };
+          selectionFrequenciesTable.Rows.Add(histoRow);
+        }
+        histoRow = selectionFrequenciesTable.Rows["SelectionFrequencies"];
+        var frequencies = new double[trees.Count];
+
+        var graph = (SymbolicExpressionTreeGenealogyGraph)results[PopulationGraphParameterName].Value;
+        // get graph nodes corresponding to individuals of the previous generation
+        var prevGen = graph.Nodes.Where(node => node.Rank == Generations.Value - 1).OrderByDescending(n => n.Quality).ToList();
+        for (int i = 0; i != prevGen.Count; ++i) {
+          int selFreq = GlobalCloneMap.Values.Count(t => t == prevGen[i].SymbolicExpressionTree);
+          frequencies[i] = selFreq;
+        }
+        histoRow.Values.Replace(frequencies);
+
+        bool storeHistory = StoreHistory.Value;
+        if (storeHistory) {
+          DataTableHistory selectionFrequenciesHistory;
+          if (!results.ContainsKey("SelectionFrequenciesHistory")) {
+            selectionFrequenciesHistory = new DataTableHistory();
+            results.Add(new Result("SelectionFrequenciesHistory", selectionFrequenciesHistory));
+          }
+          selectionFrequenciesHistory = (DataTableHistory)results["SelectionFrequenciesHistory"].Value;
+          selectionFrequenciesHistory.Add((DataTable)selectionFrequenciesTable.Clone());
+        }
       }
       return base.Apply();
     }
-
-    public bool EnabledByDefault { get { return true; } }
   }
 }
Index: anches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/Analyzers/SymbolicExpressionTreeRelativeFragmentDepthAnalyzer.cs
===================================================================
--- /branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/Analyzers/SymbolicExpressionTreeRelativeFragmentDepthAnalyzer.cs	(revision 9237)
+++ 	(revision )
@@ -1,142 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System.Collections.Generic;
-using System.Linq;
-using HeuristicLab.Analysis;
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
-using HeuristicLab.Optimization;
-using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-// type definitions for convenience
-using CloneMapType = HeuristicLab.Core.ItemDictionary<HeuristicLab.Core.IItem, HeuristicLab.Core.IItem>;
-using TraceMapType = HeuristicLab.Core.ItemDictionary<HeuristicLab.Core.IItem, HeuristicLab.Core.IItemList<HeuristicLab.Core.IItem>>;
-
-namespace HeuristicLab.EvolutionaryTracking {
-  /// <summary>
-  /// An operator that gathers information on tree fragments that get passed from one generation to the next via genetic operators
-  /// (Tracking of genetic variance and heredity)
-  /// </summary>
-  [Item("SymbolicExpressionTreeRelativeFragmentDepthAnalyzer", "An operator that provides statistics about crossover fragments")]
-  [StorableClass]
-  public sealed class SymbolicExpressionTreeRelativeFragmentDepthAnalyzer : SymbolicExpressionTreeFragmentsAnalyzer {
-    private const string RelativeFragmentDepthParameterName = "Relative fragment depth";
-    // impact values calculator
-    public ILookupParameter<DataTable> RelativeFragmentDepthParameter { get { return (ILookupParameter<DataTable>)Parameters[RelativeFragmentDepthParameterName]; } }
-
-    public DataTable RelativeFragmentDepths {
-      get { return RelativeFragmentDepthParameter.ActualValue; }
-      set { RelativeFragmentDepthParameter.ActualValue = value; }
-    }
-
-    [StorableConstructor]
-    private SymbolicExpressionTreeRelativeFragmentDepthAnalyzer(bool deserializing) : base(deserializing) { }
-    private SymbolicExpressionTreeRelativeFragmentDepthAnalyzer(SymbolicExpressionTreeRelativeFragmentDepthAnalyzer original, Cloner cloner) : base(original, cloner) { }
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new SymbolicExpressionTreeRelativeFragmentDepthAnalyzer(this, cloner);
-    }
-    public SymbolicExpressionTreeRelativeFragmentDepthAnalyzer()
-      : base() {
-      #region Add parameters
-      Parameters.Add(new LookupParameter<DataTable>(RelativeFragmentDepthParameterName));
-      #endregion
-
-      UpdateCounterParameter.Hidden = true;
-      UpdateIntervalParameter.Hidden = true;
-
-    }
-    #region After deserialization code
-
-    [StorableHook(HookType.AfterDeserialization)]
-    private void AfterDeserialization() {
-    }
-
-    #endregion
-    #region IStatefulItem members
-    public override void InitializeState() {
-      base.InitializeState();
-      UpdateCounter.Value = 0;
-    }
-
-    public override void ClearState() {
-      base.ClearState();
-      UpdateCounter.Value = 0;
-    }
-    #endregion
-
-    public override IOperation Apply() {
-      UpdateCounter.Value++;
-      if (UpdateCounter.Value == UpdateInterval.Value) {
-        UpdateCounter.Value = 0; // reset counter
-        if (Generations.Value > 1) {
-          SecondaryTraceMap = SecondaryTraceMap ?? new TraceMapType();
-          SecondaryFragmentMap = SecondaryFragmentMap ?? new CloneMapType();
-          SecondaryCloneMap = SecondaryCloneMap ?? new CloneMapType();
-
-          InitializeParameters();
-          InitializeRows();
-
-          var fragmentDepths = (from m in SecondaryFragmentMap
-                                let tree = (ISymbolicExpressionTree)m.Key
-                                let fragment = (IFragment)m.Value
-                                where fragment.Root != null
-                                select tree.Root.GetBranchLevel(fragment.Root)
-                               ).ToList();
-
-          // fragments of selected offspring
-          var selected = new HashSet<ISymbolicExpressionTree>(GlobalTraceMap.Values.SelectMany(list => list.Cast<ISymbolicExpressionTree>()));
-          var goodFragmentDepths = (from m in SecondaryFragmentMap
-                                    let tree = (ISymbolicExpressionTree)m.Key
-                                    let fragment = (IFragment)m.Value
-                                    where fragment.Root != null
-                                    where selected.Contains(tree)
-                                    select tree.Root.GetBranchLevel(fragment.Root)
-                                   ).ToList();
-
-          RelativeFragmentDepths.Rows["Average relative fragment depth (all)"].Values.Add(fragmentDepths.Count > 0 ? fragmentDepths.Average() : 0.0);
-          RelativeFragmentDepths.Rows["Average relative fragment depth (good)"].Values.Add(goodFragmentDepths.Count > 0 ? goodFragmentDepths.Average() : 0.0);
-        }
-      }
-      return base.Apply();
-    }
-
-    protected override void InitializeParameters() {
-      var results = ResultsParameter.ActualValue;
-      if (!results.ContainsKey("Relative fragment depths")) {
-        RelativeFragmentDepths = RelativeFragmentDepths ?? new DataTable("Relative fragment depths") { VisualProperties = { YAxisTitle = "Relative depth" } };
-        results.Add(new Result("Relative fragment depths", RelativeFragmentDepths));
-      }
-      base.InitializeParameters();
-    }
-
-    private void InitializeRows() {
-      string[] rowNames =
-        {
-          "Average relative fragment depth (good)", "Average relative fragment depth (all)"
-        };
-      foreach (var rowName in rowNames.Where(rowName => !RelativeFragmentDepths.Rows.ContainsKey(rowName))) {
-        RelativeFragmentDepths.Rows.Add(new DataRow(rowName) { VisualProperties = { StartIndexZero = true } });
-      }
-    }
-  } //SymbolicExpressionTreeFragmentLengthAnalyzer
-}
Index: /branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/DirectedGraph/Vertex.cs
===================================================================
--- /branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/DirectedGraph/Vertex.cs	(revision 9237)
+++ /branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/DirectedGraph/Vertex.cs	(revision 9238)
@@ -100,5 +100,4 @@
       return list;
     }
-
     // this method can be used to add arcs towards targets that are not visible in the graph 
     // (they do not appear in the nodes Dictionary). It is the programmers responsibility to 
@@ -114,5 +113,4 @@
       if (OutEdges == null) { OutEdges = new List<Arc> { arc }; } else { OutEdges.Add(arc); }
     }
-
     public void AddReverseArc(Arc arc) {
       if (arc.Target == null) { arc.Target = this; }
@@ -120,6 +118,4 @@
       if (InEdges == null) { InEdges = new List<Arc> { arc }; } else { InEdges.Add(arc); }
     }
-
-
     public void AddReverseArc(IVertex source, double weight = 0.0, object data = null) {
       var e = new Arc { Source = source, Target = this, Data = data, Weight = weight };
Index: /branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/HeuristicLab.EvolutionaryTracking-3.4.csproj
===================================================================
--- /branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/HeuristicLab.EvolutionaryTracking-3.4.csproj	(revision 9237)
+++ /branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/HeuristicLab.EvolutionaryTracking-3.4.csproj	(revision 9238)
@@ -87,11 +87,14 @@
   </ItemGroup>
   <ItemGroup>
-    <Compile Include="Analyzers\SymbolicExpressionTreeRelativeFragmentDepthAnalyzer.cs" />
-    <Compile Include="Analyzers\SymbolicExpressionTreeFragmentLengthsAnalyzer.cs" />
+    <Compile Include="Analyzers\SymbolicExpressionTreeShapeAnalyzer.cs" />
+    <Compile Include="Analyzers\SymbolicExpressionTreeEvolvabilityAnalyzer.cs" />
+    <Compile Include="Analyzers\Fragments\SymbolicExpressionTreeRelativeFragmentDepthAnalyzer.cs" />
+    <Compile Include="Analyzers\Fragments\SymbolicExpressionTreeFragmentLengthsAnalyzer.cs" />
     <Compile Include="Analyzers\GeneticOperatorsAverageImprovementAnalyzer.cs" />
-    <Compile Include="Analyzers\SymbolicExpressionTreeEvolvabilityAnalyzer.cs" />
     <Compile Include="Analyzers\SymbolicExpressionTreeFrequentPatternsAnalyzer.cs" />
-    <Compile Include="Analyzers\SymbolicExpressionTreeFragmentsAnalyzer.cs" />
+    <Compile Include="Analyzers\Fragments\SymbolicExpressionTreeFragmentsAnalyzer.cs" />
     <Compile Include="FPGraph.cs" />
+    <Compile Include="LineageExplorer.cs" />
+    <Compile Include="Operators\LineageAggregator.cs" />
     <Compile Include="Operators\SymbolicExpressionTreeFPBuilder.cs" />
     <Compile Include="Operators\SymbolicExpressionTreeGenealogyGraphBuilder.cs" />
Index: /branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/LineageExplorer.cs
===================================================================
--- /branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/LineageExplorer.cs	(revision 9238)
+++ /branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/LineageExplorer.cs	(revision 9238)
@@ -0,0 +1,20 @@
+﻿using System;
+using System.Collections.Generic;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.EvolutionaryTracking {
+  [StorableClass]
+  public class LineageExplorer : Item {
+    public ISymbolicExpressionTreeGenealogyGraph GenealogyGraph { get; set; }
+    public IList<Tuple<ISymbolicExpressionTree, double>> Trees { get; set; }
+    public int Generations { get; set; }
+
+    private LineageExplorer(bool deserializing) : base(deserializing) { }
+    private LineageExplorer(LineageExplorer original, Cloner cloner) : base(original, cloner) { }
+    public LineageExplorer() { }
+    public override IDeepCloneable Clone(Cloner cloner) { return new LineageExplorer(this, cloner); }
+  }
+}
Index: /branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/Operators/CleanupOperator.cs
===================================================================
--- /branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/Operators/CleanupOperator.cs	(revision 9237)
+++ /branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/Operators/CleanupOperator.cs	(revision 9238)
@@ -20,7 +20,10 @@
 #endregion
 
+using System.Collections.Generic;
+using System.Linq;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Data;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
 using HeuristicLab.Operators;
 using HeuristicLab.Optimization;
@@ -47,5 +50,8 @@
     private const string MaximumGenerationsParameterName = "MaximumGenerations";
     private const string ResultsParameterName = "Results";
-    private const string DeleteGenealogyGraphParameterName = "DeleteGenealogyGraph";
+    private const string CleanGenealogyGraphParameterName = "CleanGenealogyGraph";
+    private const string UpdateGenealogyGraphParameterName = "UpdateGenealogyGraph";
+    private const string SymbolicExpressionTreeParameterName = "SymbolicExpressionTree";
+    private const string SymbolicExpressionTreeQualityParameterName = "Quality";
     #endregion
 
@@ -72,31 +78,30 @@
       get { return (LookupParameter<ResultCollection>)Parameters[ResultsParameterName]; }
     }
-    public ValueParameter<BoolValue> DeleteGenealogyGraphParameter {
-      get { return (ValueParameter<BoolValue>)Parameters[DeleteGenealogyGraphParameterName]; }
+    public ValueParameter<BoolValue> CleanGenealogyGraphParameter {
+      get { return (ValueParameter<BoolValue>)Parameters[CleanGenealogyGraphParameterName]; }
+    }
+    public ValueParameter<BoolValue> UpdateGenealogyGraphParameter {
+      get { return (ValueParameter<BoolValue>)Parameters[UpdateGenealogyGraphParameterName]; }
+    }
+    public IScopeTreeLookupParameter<ISymbolicExpressionTree> SymbolicExpressionTreeParameter {
+      get { return (IScopeTreeLookupParameter<ISymbolicExpressionTree>)Parameters[SymbolicExpressionTreeParameterName]; }
+    }
+    public IScopeTreeLookupParameter<DoubleValue> SymbolicExpressionTreeQualityParameter {
+      get { return (IScopeTreeLookupParameter<DoubleValue>)Parameters[SymbolicExpressionTreeQualityParameterName]; }
     }
     #endregion
 
     #region Properties
-    public CloneMapType GlobalCloneMap {
-      get { return GlobalCloneMapParameter.ActualValue; }
-    }
-    public TraceMapType GlobalTraceMap {
-      get { return GlobalTraceMapParameter.ActualValue; }
-    }
-    public CloneMapType GlobalFragmentMap {
-      get { return GlobalFragmentMapParameter.ActualValue; }
-    }
-    public GeneticExchangeMapType GlobalGeneticExchangeMap {
-      get { return GlobalGeneticExchangeMapParameter.ActualValue; }
-    }
-    public IntValue Generations {
-      get { return GenerationsParameter.ActualValue; }
-    }
-    public IntValue MaximumGenerations {
-      get { return MaximumGenerationsParameter.ActualValue; }
-    }
-    public ResultCollection Results {
-      get { return ResultsParameter.ActualValue; }
-    }
+    private CloneMapType GlobalCloneMap { get { return GlobalCloneMapParameter.ActualValue; } }
+    private TraceMapType GlobalTraceMap { get { return GlobalTraceMapParameter.ActualValue; } }
+    private CloneMapType GlobalFragmentMap { get { return GlobalFragmentMapParameter.ActualValue; } }
+    private GeneticExchangeMapType GlobalGeneticExchangeMap { get { return GlobalGeneticExchangeMapParameter.ActualValue; } }
+    private IntValue Generations { get { return GenerationsParameter.ActualValue; } }
+    private IntValue MaximumGenerations { get { return MaximumGenerationsParameter.ActualValue; } }
+    private ResultCollection Results { get { return ResultsParameter.ActualValue; } }
+    public BoolValue CleanGenealogyGraph { get { return CleanGenealogyGraphParameter.Value; } }
+    public BoolValue UpdateGenealogyGraph { get { return UpdateGenealogyGraphParameter.Value; } }
+    private IEnumerable<DoubleValue> Quality { get { return SymbolicExpressionTreeQualityParameter.ActualValue; } }
+    private IEnumerable<ISymbolicExpressionTree> SymbolicExpressionTree { get { return SymbolicExpressionTreeParameter.ActualValue; } }
     #endregion
 
@@ -105,4 +110,12 @@
       if (!Parameters.ContainsKey(GlobalGeneticExchangeMapParameterName))
         Parameters.Add(new LookupParameter<GeneticExchangeMapType>(GlobalGeneticExchangeMapParameterName));
+      if (!Parameters.ContainsKey(CleanGenealogyGraphParameterName))
+        Parameters.Add(new ValueParameter<BoolValue>(CleanGenealogyGraphParameterName));
+      if (!Parameters.ContainsKey(UpdateGenealogyGraphParameterName))
+        Parameters.Add(new ValueParameter<BoolValue>(UpdateGenealogyGraphParameterName));
+      if (!Parameters.ContainsKey(SymbolicExpressionTreeParameterName))
+        Parameters.Add(new ScopeTreeLookupParameter<ISymbolicExpressionTree>(SymbolicExpressionTreeParameterName, "The symbolic expression trees to analyze."));
+      if (!Parameters.ContainsKey(SymbolicExpressionTreeQualityParameterName))
+        Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>(SymbolicExpressionTreeQualityParameterName, "The qualities of the symbolic expression trees"));
     }
 
@@ -121,4 +134,8 @@
       Parameters.Add(new LookupParameter<IntValue>(MaximumGenerationsParameterName));
       Parameters.Add(new ValueLookupParameter<ResultCollection>(ResultsParameterName, "The results collection where the analysis values should be stored."));
+      Parameters.Add(new ValueParameter<BoolValue>(CleanGenealogyGraphParameterName));
+      Parameters.Add(new ValueParameter<BoolValue>(UpdateGenealogyGraphParameterName));
+      Parameters.Add(new ScopeTreeLookupParameter<ISymbolicExpressionTree>(SymbolicExpressionTreeParameterName, "The symbolic expression trees to analyze."));
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>(SymbolicExpressionTreeQualityParameterName, "The qualities of the symbolic expression trees"));
     }
 
@@ -129,12 +146,28 @@
       if (GlobalGeneticExchangeMap != null) GlobalGeneticExchangeMap.Clear();
 
+      if (!Results.ContainsKey(PopulationGraphParameterName)) return base.Apply();
+      var graph = (SymbolicExpressionTreeGenealogyGraph)Results[PopulationGraphParameterName].Value;
+      if (graph == null) return base.Apply();
+
+      if (UpdateGenealogyGraph.Value) {
+        // update vertex qualities if the trees in the scope were optimized by the ConstantOptimizationAnalyzer
+        ISymbolicExpressionTree[] trees = SymbolicExpressionTree.ToArray();
+        double[] qualities = Quality.Select(x => x.Value).ToArray();
+
+        for (int i = 0; i != trees.Length; ++i) {
+          foreach (var graphNode in graph.GetGraphNodes(trees[i])) {
+            graphNode.Quality = qualities[i];
+          }
+        }
+      }
+
       // if we are at the end of the run, then we clear the genealogy graph (to save memory)
-      if (Generations.Value == MaximumGenerations.Value)
-        if (Results.ContainsKey(PopulationGraphParameterName)) {
-          var graph = (SymbolicExpressionTreeGenealogyGraph)Results[PopulationGraphParameterName].Value;
-          Results.Remove(PopulationGraphParameterName);
-          graph.Dispose();
-        }
-
+      if (CleanGenealogyGraph.Value) {
+        if (Generations.Value == MaximumGenerations.Value)
+          if (Results.ContainsKey(PopulationGraphParameterName)) {
+            Results.Remove(PopulationGraphParameterName);
+            graph.Dispose();
+          }
+      }
       return base.Apply();
     }
Index: /branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/Operators/LineageAggregator.cs
===================================================================
--- /branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/Operators/LineageAggregator.cs	(revision 9238)
+++ /branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/Operators/LineageAggregator.cs	(revision 9238)
@@ -0,0 +1,101 @@
+﻿using System;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.EvolutionaryTracking {
+  /// <summary>
+  /// This operator basically aggregates together a scope list of trees in the current generation and the genealogy graph so far
+  /// in a new object that can be used as Content for the InteractiveIndividualHistoryView
+  /// </summary>
+  [StorableClass]
+  public class GenealogyAggregator : SingleSuccessorOperator {
+    private const string PopulationGraphParameterName = "PopulationGraph";
+    private const string LineageExplorerParameterName = "LineageExplorer";
+    private const string ResultsParameterName = "Results";
+    private const string GenerationsParameterName = "Generations";
+    private const string MaximumGenerationsParameterName = "MaximumGenerations";
+
+    private const string SymbolicExpressionTreeParameterName = "SymbolicExpressionTree";
+    private const string SymbolicExpressionTreeQualityParameterName = "Quality";
+
+    #region Parameter properties
+    public IScopeTreeLookupParameter<ISymbolicExpressionTree> SymbolicExpressionTreeParameter {
+      get { return (IScopeTreeLookupParameter<ISymbolicExpressionTree>)Parameters[SymbolicExpressionTreeParameterName]; }
+    }
+    public IScopeTreeLookupParameter<DoubleValue> SymbolicExpressionTreeQualityParameter {
+      get { return (IScopeTreeLookupParameter<DoubleValue>)Parameters[SymbolicExpressionTreeQualityParameterName]; }
+    }
+    public LookupParameter<ResultCollection> ResultsParameter {
+      get { return (LookupParameter<ResultCollection>)Parameters[ResultsParameterName]; }
+    }
+    public LookupParameter<IntValue> GenerationsParameter {
+      get { return (LookupParameter<IntValue>)Parameters[GenerationsParameterName]; }
+    }
+    public LookupParameter<IntValue> MaximumGenerationsParameter {
+      get { return (LookupParameter<IntValue>)Parameters[MaximumGenerationsParameterName]; }
+    }
+    #endregion
+    #region Properties
+    public bool EnabledByDefault {
+      get { return true; }
+    }
+    public ResultCollection Results {
+      get { return ResultsParameter.ActualValue; }
+    }
+    public IntValue Generations {
+      get { return GenerationsParameter.ActualValue; }
+    }
+    public IntValue MaximumGenerations {
+      get { return MaximumGenerationsParameter.ActualValue; }
+    }
+    #endregion
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() { }
+
+    #region IStatefulItem members
+    public override void InitializeState() {
+      base.InitializeState();
+    }
+
+    public override void ClearState() {
+      base.ClearState();
+    }
+    #endregion
+
+    [StorableConstructor]
+    private GenealogyAggregator(bool deserializing) : base(deserializing) { }
+    private GenealogyAggregator(GenealogyAggregator original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) { return new GenealogyAggregator(this, cloner); }
+    public GenealogyAggregator() {
+      #region Add parameters
+      Parameters.Add(new LookupParameter<IntValue>(GenerationsParameterName, "The number of generations so far."));
+      Parameters.Add(new LookupParameter<IntValue>(MaximumGenerationsParameterName, "The maximum number of generations"));
+      Parameters.Add(new ValueLookupParameter<ResultCollection>(ResultsParameterName, "The results collection where the analysis values should be stored."));
+      Parameters.Add(new ScopeTreeLookupParameter<ISymbolicExpressionTree>(SymbolicExpressionTreeParameterName, "The symbolic expression trees to analyze"));
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>(SymbolicExpressionTreeQualityParameterName, "The qualities of the symbolic expression trees"));
+      #endregion
+    }
+
+    public override IOperation Apply() {
+      if (!Results.ContainsKey(PopulationGraphParameterName)) return base.Apply();
+      var graph = (SymbolicExpressionTreeGenealogyGraph)Results[PopulationGraphParameterName].Value;
+      var trees = SymbolicExpressionTreeParameter.ActualValue;
+      var qualities = SymbolicExpressionTreeQualityParameter.ActualValue;
+      var tuples = trees.Zip(qualities, (t, q) => new Tuple<ISymbolicExpressionTree, double>(t, q.Value)).ToList();
+      var lineageExplorer = new LineageExplorer { GenealogyGraph = graph, Trees = tuples, Generations = Generations.Value };
+      if (!Results.ContainsKey(LineageExplorerParameterName))
+        Results.Add(new Result(LineageExplorerParameterName, lineageExplorer));
+      else Results[LineageExplorerParameterName].Value = lineageExplorer; 
+
+      return base.Apply();
+    }
+  }
+}
Index: /branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/Operators/SymbolicExpressionTreeGenealogyGraphBuilder.cs
===================================================================
--- /branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/Operators/SymbolicExpressionTreeGenealogyGraphBuilder.cs	(revision 9237)
+++ /branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/Operators/SymbolicExpressionTreeGenealogyGraphBuilder.cs	(revision 9238)
@@ -21,5 +21,4 @@
 
 using System;
-using System.Collections.Generic;
 using System.Linq;
 using System.Threading;
@@ -63,5 +62,5 @@
     private const string SymbolicExpressionTreeQualityParameterName = "Quality";
     #endregion
-    #region Parameter properties
+    #region Parameters
     public IScopeTreeLookupParameter<ISymbolicExpressionTree> SymbolicExpressionTreeParameter {
       get { return (IScopeTreeLookupParameter<ISymbolicExpressionTree>)Parameters[SymbolicExpressionTreeParameterName]; }
@@ -109,5 +108,5 @@
     }
     #endregion
-    #region Properties
+    #region Parameter properties
     public bool EnabledByDefault {
       get { return true; }
@@ -189,6 +188,4 @@
 
     public override IOperation Apply() {
-      if (GlobalTraceMap == null) return base.Apply(); // no trace map, no genealogy graph
-
       if (!Parameters.ContainsKey("Results")) return base.Apply();
 
@@ -211,17 +208,38 @@
       var pairs = trees.Zip(qualities, (t, q) => new { Tree = t, Quality = q.Value }).OrderByDescending(x => x.Quality).ToList();
 
-      var graphNodes = new List<SymbolicExpressionGenealogyGraphNode>(
-        (from i in Enumerable.Range(0, trees.Length)
-         let tree = pairs[i].Tree
-         let quality = pairs[i].Quality
-         select new SymbolicExpressionGenealogyGraphNode { SymbolicExpressionTree = tree, Quality = quality, Rank = generation, IsElite = i < Elites.Value }
-        ).Concat
-        (from t in trees
-         where GlobalTraceMap.ContainsKey(t)
-         let parents = GlobalTraceMap[t]
-         where parents.Count == 1 // 1 parent means mutation
-         let p = (ISymbolicExpressionTree)parents[0]
-         select new SymbolicExpressionGenealogyGraphNode { SymbolicExpressionTree = p, Quality = Evaluate(p), Rank = generation - 0.5 }
-        )).ToList();
+      if (generation == 0) {
+        // add the trees in the graph and return
+        foreach (var pair in pairs) {
+          var tree = pair.Tree;
+          var quality = pair.Quality;
+          graph.AddNode(new SymbolicExpressionGenealogyGraphNode {
+            SymbolicExpressionTree = tree, Quality = quality, Rank = generation
+          });
+        }
+        return base.Apply();
+      }
+
+      var graphNodes = (from i in Enumerable.Range(0, trees.Length)
+                        let tree = pairs[i].Tree
+                        let quality = pairs[i].Quality
+                        select new SymbolicExpressionGenealogyGraphNode {
+                          SymbolicExpressionTree = tree,
+                          Quality = quality,
+                          Rank = generation,
+                          IsElite = i < Elites.Value
+                        }).Concat
+        // the following query addds the intermediate nodes that were created when 
+        // crossover was followed by mutation (they are not present in the scope) 
+                        (from t in trees
+                         where GlobalTraceMap.ContainsKey(t)
+                         let parents = GlobalTraceMap[t]
+                         where parents.Count == 1 // 1 parent means mutation
+                         let p = (ISymbolicExpressionTree)parents[0]
+                         select new SymbolicExpressionGenealogyGraphNode {
+                           SymbolicExpressionTree = p,
+                           Quality = Evaluate(p),
+                           Rank = generation - 0.5 // an intermediate parent that would normale be 'invisible' to the evolutionary process
+                         }
+                        ).ToList();
 
       foreach (var node in graphNodes) {
@@ -229,13 +247,21 @@
       }
 
+      graphNodes.Sort((a, b) => b.Rank.CompareTo(a.Rank));
+
       foreach (var node in graphNodes) {
         var tree = node.SymbolicExpressionTree;
-        if (!GlobalTraceMap.ContainsKey(tree)) continue;
+        if (!GlobalTraceMap.ContainsKey(tree)) {
+          continue;
+        }
         var parents = GlobalTraceMap[tree].Cast<ISymbolicExpressionTree>();
         foreach (var p in parents) {
           var nodes = graph.GetGraphNodes(p);
-          if (nodes == null) continue;
+          if (nodes == null) {
+            throw new Exception("Node cannot have no parents");
+          }
           var sourceNode = nodes.LastOrDefault(n => n.Rank < node.Rank);
-          if (sourceNode == null) continue;
+          if (sourceNode == null) {
+            throw new Exception("Source node cannot be null");
+          }
           var arc = new Arc { Source = sourceNode, Target = node, Data = GlobalFragmentMap[tree] };
           sourceNode.AddForwardArc(arc);
@@ -249,6 +275,6 @@
     /// Evaluate a symbolic expression tree. We perform evaluation by adding a temporary subscope with the tree in it, and calling evaluator.Apply()
     /// </summary>
-    /// <param name="tree"></param>
-    /// <returns></returns>
+    /// <param name="tree">The symbolic expression tree to evaluate</param>
+    /// <returns>A double value representing the fitness</returns>
     private double Evaluate(IItem tree) {
       var subScope = new Scope();
