Index: /branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/BuildingBlockAnalyzers/SymbolicDataAnalysisPoly10Analyzer.cs
===================================================================
--- /branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/BuildingBlockAnalyzers/SymbolicDataAnalysisPoly10Analyzer.cs	(revision 11461)
+++ /branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/BuildingBlockAnalyzers/SymbolicDataAnalysisPoly10Analyzer.cs	(revision 11462)
@@ -46,5 +46,5 @@
     private const string UpdateCounterParameterName = "UpdateCounter";
     private const string UpdateIntervalParameterName = "UpdateInterval";
-    private const string buildingBlocksFrequenciesTableName = "Building blocks frequencies";
+    private const string BuildingBlocksFrequenciesTableName = "Building blocks frequencies";
 
 
@@ -175,5 +175,5 @@
         }
       }
-      var table = (DataTable)results[buildingBlocksFrequenciesTableName].Value;
+      var table = (DataTable)results[BuildingBlocksFrequenciesTableName].Value;
       foreach (var pair in bbFrequencies) {
         var label = prettyLabels[pair.Key];
@@ -232,9 +232,9 @@
       var results = ResultCollectionParameter.ActualValue;
       DataTable table;
-      if (!results.ContainsKey(buildingBlocksFrequenciesTableName)) {
-        table = new DataTable(buildingBlocksFrequenciesTableName);
-        results.Add(new Result(buildingBlocksFrequenciesTableName, table));
+      if (!results.ContainsKey(BuildingBlocksFrequenciesTableName)) {
+        table = new DataTable(BuildingBlocksFrequenciesTableName);
+        results.Add(new Result(BuildingBlocksFrequenciesTableName, table));
       } else {
-        table = (DataTable)results[buildingBlocksFrequenciesTableName].Value;
+        table = (DataTable)results[BuildingBlocksFrequenciesTableName].Value;
       }
       table.Rows.Clear();
Index: /branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisUsefulGenesAnalyzer.cs
===================================================================
--- /branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisUsefulGenesAnalyzer.cs	(revision 11461)
+++ /branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisUsefulGenesAnalyzer.cs	(revision 11462)
@@ -45,7 +45,10 @@
     private const string UpdateCounterParameterName = "UpdateCounter";
     private const string UpdateIntervalParameterName = "UpdateInterval";
+    private const string MinimumGenerationsParameterName = "MinimumGenerations";
     private const string PruningProbabilityParameterName = "PruningProbability";
     private const string PercentageOfBestSolutionsParameterName = "PercentageOfBestSolutions";
     private const string PromotedSubtreesResultName = "Promoted subtrees";
+    private const string AverageQualityImprovementResultName = "Average quality improvement";
+    private const string AverageLengthReductionResultName = "Average length reduction";
     private const string RandomParameterName = "Random";
 
@@ -85,4 +88,8 @@
     public ValueParameter<IntValue> UpdateIntervalParameter {
       get { return (ValueParameter<IntValue>)Parameters[UpdateIntervalParameterName]; }
+    }
+
+    public ValueParameter<IntValue> MinimumGenerationsParameter {
+      get { return (ValueParameter<IntValue>)Parameters[MinimumGenerationsParameterName]; }
     }
 
@@ -105,4 +112,9 @@
       get { return UpdateIntervalParameter.Value.Value; }
       set { UpdateIntervalParameter.Value.Value = value; }
+    }
+
+    public int MinimumGenerations {
+      get { return MinimumGenerationsParameter.Value.Value; }
+      set { MinimumGenerationsParameter.Value.Value = value; }
     }
 
@@ -129,6 +141,7 @@
       Parameters.Add(new ValueParameter<IntValue>(UpdateCounterParameterName, new IntValue(0)));
       Parameters.Add(new ValueParameter<IntValue>(UpdateIntervalParameterName, new IntValue(1)));
-      Parameters.Add(new ValueParameter<PercentValue>(PercentageOfBestSolutionsParameterName, "How many of the best individuals should be pruned using this method."));
-      Parameters.Add(new ValueParameter<PercentValue>(PruningProbabilityParameterName, "The probability to apply pruning"));
+      Parameters.Add(new ValueParameter<IntValue>(MinimumGenerationsParameterName, "The minimum number of generations the algorithm must be let to evolve before applying this analyzer.", new IntValue(50)));
+      Parameters.Add(new ValueParameter<PercentValue>(PercentageOfBestSolutionsParameterName, "How many of the best individuals should be pruned using this method.", new PercentValue(1.0)));
+      Parameters.Add(new ValueParameter<PercentValue>(PruningProbabilityParameterName, "The probability to apply pruning", new PercentValue(0.1)));
       #endregion
     }
@@ -150,6 +163,14 @@
     }
 
+    public override void InitializeState() {
+      UpdateCounter = 0;
+      base.InitializeState();
+    }
+
     public override IOperation Apply() {
+      int generations = GenerationsParameter.ActualValue.Value;
       #region Update counter & update interval
+      if (generations < MinimumGenerations)
+        return base.Apply();
       UpdateCounter++;
       if (UpdateCounter != UpdateInterval) {
@@ -162,6 +183,5 @@
       var qualities = QualityParameter.ActualValue.ToArray();
 
-      // order trees by quality
-      Array.Sort(qualities, trees);
+      Array.Sort(qualities, trees); // sort trees array based on qualities
 
       var interpreter = SymbolicDataAnalysisTreeInterpreterParameter.ActualValue;
@@ -171,23 +191,34 @@
 
       int replacedTrees = 0;
+      int avgLengthReduction = 0;
+      double avgQualityImprovement = 0;
 
       var count = (int)Math.Floor(trees.Length * PercentageOfBestSolutions);
 
-      for (int i = 0; i < count; ++i) {
+      for (int i = trees.Length - 1; i >= trees.Length - count; --i) {
+        if (random.NextDouble() > PruningProbability) continue;
         var tree = trees[i];
         var quality = qualities[i].Value;
         var root = tree.Root.GetSubtree(0).GetSubtree(0);
 
-        foreach (var s in root.IterateNodesPrefix()) {
-          if (random.NextDouble() < PruningProbability) continue;
+        foreach (var s in root.IterateNodesPrefix().Skip(1)) {
           var r2 = EvaluateSubtree(s, interpreter, problemData, rows);
-          if (s == root || r2 < quality) continue;
+          if (double.IsNaN(r2) || r2 <= quality) continue;
+          avgQualityImprovement += (r2 - quality);
+          avgLengthReduction += (tree.Length - s.GetLength());
+          replacedTrees++;
+          // replace tree with its own subtree
           var startNode = tree.Root.GetSubtree(0);
           startNode.RemoveSubtree(0);
           startNode.AddSubtree(s);
-          replacedTrees++;
+          // update tree quality
+          qualities[i].Value = r2;
+
           break;
         }
       }
+
+      avgQualityImprovement /= replacedTrees;
+      avgLengthReduction = (int)Math.Round((double)avgLengthReduction / replacedTrees);
 
       var results = ResultCollectionParameter.ActualValue;
@@ -202,4 +233,22 @@
       table.Rows[PromotedSubtreesResultName].Values.Add(replacedTrees);
 
+      if (results.ContainsKey(AverageQualityImprovementResultName)) {
+        table = (DataTable)results[AverageQualityImprovementResultName].Value;
+      } else {
+        table = new DataTable(AverageQualityImprovementResultName);
+        table.Rows.Add(new DataRow(AverageQualityImprovementResultName));
+        results.Add(new Result(AverageQualityImprovementResultName, table));
+      }
+      table.Rows[AverageQualityImprovementResultName].Values.Add(avgQualityImprovement);
+
+      if (results.ContainsKey(AverageLengthReductionResultName)) {
+        table = (DataTable)results[AverageLengthReductionResultName].Value;
+      } else {
+        table = new DataTable(AverageLengthReductionResultName);
+        table.Rows.Add(new DataRow(AverageLengthReductionResultName));
+        results.Add(new Result(AverageLengthReductionResultName, table));
+      }
+      table.Rows[AverageLengthReductionResultName].Values.Add(avgLengthReduction);
+
       return base.Apply();
     }
