Index: /branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/Analyzers/FixedValidationBestScaledSymbolicRegressionSolutionAnalyzer.cs
===================================================================
--- /branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/Analyzers/FixedValidationBestScaledSymbolicRegressionSolutionAnalyzer.cs	(revision 4296)
+++ /branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/Analyzers/FixedValidationBestScaledSymbolicRegressionSolutionAnalyzer.cs	(revision 4297)
@@ -146,4 +146,7 @@
       get { return (ScopeTreeLookupParameter<DoubleValue>)Parameters["Quality"]; }
     }
+    public ScopeTreeLookupParameter<DoubleValue> ValidationQualityParameter {
+      get { return (ScopeTreeLookupParameter<DoubleValue>)Parameters["ValidationQuality"]; }
+    }
 
     public ILookupParameter<IntValue> GenerationsParameter {
@@ -237,4 +240,5 @@
       Parameters.Add(new LookupParameter<SymbolicRegressionSolution>("BestTrainingSolution"));
       Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("Quality"));
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("ValidationQuality"));
       Parameters.Add(new LookupParameter<IntValue>(GenerationsParameterName, "The number of generations calculated so far."));
       Parameters.Add(new LookupParameter<DoubleValue>(BestSolutionQualityParameterName, "The quality of the best symbolic regression solution."));
@@ -267,4 +271,7 @@
         Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("Quality"));
       }
+      if (!Parameters.ContainsKey("ValidationQuality")) {
+        Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("ValidationQuality"));
+      }
       #endregion
     }
@@ -291,4 +298,5 @@
       SymbolicExpressionTree bestTrainingTree = trees[0];
       double bestTrainingQuality = qualities[0].Value;
+      ItemArray<DoubleValue> validationQualites = new ItemArray<DoubleValue>(qualities.Length);
       for (int i = 0; i < trees.Length; i++) {
         SymbolicExpressionTree tree = trees[i];
@@ -297,5 +305,5 @@
           ProblemData.Dataset, targetVariable,
          rows);
-
+        validationQualites[i] = new DoubleValue(quality);
         if ((Maximization.Value && quality > bestQuality) ||
             (!Maximization.Value && quality < bestQuality)) {
@@ -309,4 +317,5 @@
         }
       }
+      ValidationQualityParameter.ActualValue = validationQualites;
 
       var scaledBestTrainingTree = GetScaledTree(bestTrainingTree);
Index: /branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/Analyzers/OverfittingAnalyzer.cs
===================================================================
--- /branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/Analyzers/OverfittingAnalyzer.cs	(revision 4296)
+++ /branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/Analyzers/OverfittingAnalyzer.cs	(revision 4297)
@@ -61,4 +61,7 @@
       get { return (ScopeTreeLookupParameter<DoubleValue>)Parameters["Quality"]; }
     }
+    public ScopeTreeLookupParameter<DoubleValue> ValidationQualityParameter {
+      get { return (ScopeTreeLookupParameter<DoubleValue>)Parameters["ValidationQuality"]; }
+    }
     public IValueLookupParameter<ISymbolicExpressionTreeInterpreter> SymbolicExpressionTreeInterpreterParameter {
       get { return (IValueLookupParameter<ISymbolicExpressionTreeInterpreter>)Parameters[SymbolicExpressionTreeInterpreterParameterName]; }
@@ -163,4 +166,5 @@
       Parameters.Add(new ScopeTreeLookupParameter<SymbolicExpressionTree>(SymbolicExpressionTreeParameterName, "The symbolic expression trees to analyze."));
       Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("Quality"));
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("ValidationQuality"));
       Parameters.Add(new LookupParameter<BoolValue>(MaximizationParameterName, "The direction of optimization."));
       Parameters.Add(new ValueLookupParameter<ISymbolicExpressionTreeInterpreter>(SymbolicExpressionTreeInterpreterParameterName, "The interpreter that should be used for the analysis of symbolic expression trees."));
@@ -180,5 +184,5 @@
       Parameters.Add(new LookupParameter<DoubleValue>("InitialTrainingQuality"));
       Parameters.Add(new LookupParameter<DoubleMatrix>("TrainingAndValidationQualities"));
-      Parameters.Add(new ValueLookupParameter<DoubleValue>("Percentile", new DoubleValue(0.1)));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("Percentile", new DoubleValue(1)));
 
     }
@@ -202,5 +206,8 @@
       }
       if (!Parameters.ContainsKey("Percentile")) {
-        Parameters.Add(new ValueLookupParameter<DoubleValue>("Percentile", new DoubleValue(0.1)));
+        Parameters.Add(new ValueLookupParameter<DoubleValue>("Percentile", new DoubleValue(1)));
+      }
+      if (!Parameters.ContainsKey("ValidationQuality")) {
+        Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("ValidationQuality"));
       }
     }
@@ -209,4 +216,5 @@
       var trees = SymbolicExpressionTree;
       ItemArray<DoubleValue> qualities = QualityParameter.ActualValue;
+      ItemArray<DoubleValue> validationQualities = ValidationQualityParameter.ActualValue;
 
       string targetVariable = ProblemData.TargetVariable.Value;
@@ -226,22 +234,22 @@
       //SymbolicExpressionTree bestTree = null;
 
-      List<double> validationQualities = new List<double>();
-      foreach (var tree in trees) {
-        double quality = Evaluator.Evaluate(SymbolicExpressionTreeInterpreter, tree,
-          lowerEstimationLimit, upperEstimationLimit,
-          ProblemData.Dataset, targetVariable,
-         rows);
-        validationQualities.Add(quality);
-        //if ((Maximization.Value && quality > bestQuality) ||
-        //    (!Maximization.Value && quality < bestQuality)) {
-        //  bestQuality = quality;
-        //  bestTree = tree;
-        //}
-      }
+      //List<double> validationQualities = new List<double>();
+      //foreach (var tree in trees) {
+      //  double quality = Evaluator.Evaluate(SymbolicExpressionTreeInterpreter, tree,
+      //    lowerEstimationLimit, upperEstimationLimit,
+      //    ProblemData.Dataset, targetVariable,
+      //   rows);
+      //  validationQualities.Add(quality);
+      //  //if ((Maximization.Value && quality > bestQuality) ||
+      //  //    (!Maximization.Value && quality < bestQuality)) {
+      //  //  bestQuality = quality;
+      //  //  bestTree = tree;
+      //  //}
+      //}
 
       //if (RelativeValidationQualityParameter.ActualValue == null) {
       // first call initialize the relative quality using the difference between average training and validation quality
       double avgTrainingQuality = qualities.Select(x => x.Value).Median();
-      double avgValidationQuality = validationQualities.Median();
+      double avgValidationQuality = validationQualities.Select(x => x.Value).Median();
 
       if (Maximization.Value)
@@ -254,6 +262,5 @@
       // best first (only for maximization
       var orderedDistinctPairs = (from index in Enumerable.Range(0, qualities.Length)
-                                  select new { Training = qualities[index].Value, Validation = validationQualities[index] })
-                                 .Distinct()
+                                  select new { Training = qualities[index].Value, Validation = validationQualities[index].Value })
                                  .OrderBy(x => -x.Training)
                                  .ToList();
Index: /branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/Analyzers/SymbolicRegressionTournamentPruning.cs
===================================================================
--- /branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/Analyzers/SymbolicRegressionTournamentPruning.cs	(revision 4296)
+++ /branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/Analyzers/SymbolicRegressionTournamentPruning.cs	(revision 4297)
@@ -31,4 +31,5 @@
 using HeuristicLab.Problems.DataAnalysis.Symbolic.Symbols;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using System;
 
 namespace HeuristicLab.Problems.DataAnalysis.Regression.Symbolic.Analyzers {
@@ -62,4 +63,7 @@
       get { return (ScopeTreeLookupParameter<SymbolicExpressionTree>)Parameters[SymbolicExpressionTreeParameterName]; }
     }
+    public ScopeTreeLookupParameter<DoubleValue> QualityParameter {
+      get { return (ScopeTreeLookupParameter<DoubleValue>)Parameters["Quality"]; }
+    }
     public ILookupParameter<DataAnalysisProblemData> DataAnalysisProblemDataParameter {
       get { return (ILookupParameter<DataAnalysisProblemData>)Parameters[DataAnalysisProblemDataParameterName]; }
@@ -80,4 +84,7 @@
       get { return (IValueLookupParameter<IntValue>)Parameters[SamplesEndParameterName]; }
     }
+    public IValueLookupParameter<PercentValue> RelativeNumberOfEvaluatedRowsParameters {
+      get { return (IValueLookupParameter<PercentValue>)Parameters["RelativeNumberOfEvaluatedRows"]; }
+    }
     public ILookupParameter<ISymbolicRegressionEvaluator> EvaluatorParameter {
       get { return (ILookupParameter<ISymbolicRegressionEvaluator>)Parameters[EvaluatorParameterName]; }
@@ -115,4 +122,7 @@
     public ILookupParameter<ResultCollection> ResultsParameter {
       get { return (ILookupParameter<ResultCollection>)Parameters[ResultsParameterName]; }
+    }
+    public IValueLookupParameter<BoolValue> ApplyPruningParameter {
+      get { return (IValueLookupParameter<BoolValue>)Parameters["ApplyPruning"]; }
     }
     #endregion
@@ -176,4 +186,5 @@
     }
     #endregion
+    [StorableConstructor]
     protected SymbolicRegressionTournamentPruning(bool deserializing) : base(deserializing) { }
     public SymbolicRegressionTournamentPruning()
@@ -181,4 +192,5 @@
       Parameters.Add(new LookupParameter<IRandom>(RandomParameterName, "A random number generator."));
       Parameters.Add(new ScopeTreeLookupParameter<SymbolicExpressionTree>(SymbolicExpressionTreeParameterName, "The symbolic expression trees to prune."));
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("Quality"));
       Parameters.Add(new LookupParameter<DataAnalysisProblemData>(DataAnalysisProblemDataParameterName, "The data analysis problem data to use for branch impact evaluation."));
       Parameters.Add(new LookupParameter<ISymbolicExpressionTreeInterpreter>(SymbolicExpressionTreeInterpreterParameterName, "The interpreter to use for node impact evaluation"));
@@ -187,4 +199,5 @@
       Parameters.Add(new LookupParameter<ISymbolicRegressionEvaluator>(EvaluatorParameterName, "The evaluator that should be used to determine which branches are not relevant."));
       Parameters.Add(new LookupParameter<BoolValue>(MaximizationParameterName, "The direction of optimization."));
+      Parameters.Add(new ValueLookupParameter<BoolValue>("ApplyPruning"));
       Parameters.Add(new ValueLookupParameter<DoubleValue>(MaxPruningRatioParameterName, "The maximal relative size of the pruned branch.", new DoubleValue(0.5)));
       Parameters.Add(new ValueLookupParameter<IntValue>(TournamentSizeParameterName, "The number of branches to compare for pruning", new IntValue(10)));
@@ -199,4 +212,5 @@
       Parameters.Add(new LookupParameter<IntValue>(GenerationParameterName, "The current generation."));
       Parameters.Add(new LookupParameter<ResultCollection>(ResultsParameterName, "The results collection."));
+      Parameters.Add(new ValueLookupParameter<PercentValue>("RelativeNumberOfEvaluatedRows", new PercentValue(1.0)));
     }
 
@@ -210,4 +224,14 @@
         Parameters.Add(new LookupParameter<BoolValue>(MaximizationParameterName, "The direction of optimization."));
       }
+      if (!Parameters.ContainsKey("ApplyPruning")) {
+        Parameters.Add(new ValueLookupParameter<BoolValue>("ApplyPruning"));
+      }
+      if (!Parameters.ContainsKey("Quality")) {
+        Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("Quality"));
+      }
+      if (!Parameters.ContainsKey("RelativeNumberOfEvaluatedRows")) {
+        Parameters.Add(new ValueLookupParameter<PercentValue>("RelativeNumberOfEvaluatedRows", new PercentValue(1.0)));
+      }
+
       #endregion
     }
@@ -215,4 +239,5 @@
     public override IOperation Apply() {
       bool pruningCondition =
+        (ApplyPruningParameter.ActualValue.Value) &&
         (Generation.Value >= FirstPruningGeneration.Value) &&
         ((Generation.Value - FirstPruningGeneration.Value) % PruningFrequency.Value == 0);
@@ -222,10 +247,15 @@
         double percentileEnd = PopulationPercentileEnd.Value;
         // for each tree in the given percentile
-        var trees = SymbolicExpressionTree
-          .Skip((int)(n * percentileStart))
-          .Take((int)(n * (percentileEnd - percentileStart)));
-        foreach (var tree in trees) {
-          Prune(Random, tree, Iterations.Value, TournamentSize.Value,
-            DataAnalysisProblemData, SamplesStart.Value, SamplesEnd.Value,
+        ItemArray<SymbolicExpressionTree> trees = SymbolicExpressionTree;
+        ItemArray<DoubleValue> quality = QualityParameter.ActualValue;
+        bool maximization = Maximization.Value;
+        var selectedTrees = (from index in Enumerable.Range(0, n)
+                             orderby maximization ? -quality[index].Value : quality[index].Value
+                             select new { Tree = trees[index], Quality = quality[index] })
+                                                            .Skip((int)(n * percentileStart))
+                                                            .Take((int)(n * (percentileEnd - percentileStart)));
+        foreach (var pair in selectedTrees) {
+          Prune(Random, pair.Tree, pair.Quality, Iterations.Value, TournamentSize.Value,
+            DataAnalysisProblemData, SamplesStart.Value, SamplesEnd.Value, RelativeNumberOfEvaluatedRowsParameters.ActualValue.Value,
             SymbolicExpressionTreeInterpreter, Evaluator, Maximization.Value,
             LowerEstimationLimit.Value, UpperEstimationLimit.Value,
@@ -236,16 +266,14 @@
     }
 
-    public static void Prune(IRandom random, SymbolicExpressionTree tree, int iterations, int tournamentSize,
-      DataAnalysisProblemData problemData, int samplesStart, int samplesEnd,
+    public static void Prune(IRandom random, SymbolicExpressionTree tree, DoubleValue quality, int iterations, int tournamentSize,
+      DataAnalysisProblemData problemData, int samplesStart, int samplesEnd, double relativeNumberOfEvaluatedRows,
       ISymbolicExpressionTreeInterpreter interpreter, ISymbolicRegressionEvaluator evaluator, bool maximization,
       double lowerEstimationLimit, double upperEstimationLimit,
       double maxPruningRatio, double qualityGainWeight) {
-      IEnumerable<int> rows = Enumerable.Range(samplesStart, samplesEnd - samplesStart);
+
+      IEnumerable<int> rows = RandomEnumerable.SampleRandomNumbers(samplesStart, samplesEnd, (int)Math.Ceiling((samplesEnd - samplesStart) * relativeNumberOfEvaluatedRows));
       int originalSize = tree.Size;
-      double originalQuality = evaluator.Evaluate(interpreter, tree,
-        lowerEstimationLimit, upperEstimationLimit, problemData.Dataset, problemData.TargetVariable.Value, rows);
 
       int minPrunedSize = (int)(originalSize * (1 - maxPruningRatio));
-
       // tree for branch evaluation
       SymbolicExpressionTree templateTree = (SymbolicExpressionTree)tree.Clone();
@@ -253,4 +281,5 @@
 
       SymbolicExpressionTree prunedTree = tree;
+      double currentQuality = quality.Value;
       for (int iteration = 0; iteration < iterations; iteration++) {
         SymbolicExpressionTree iterationBestTree = prunedTree;
@@ -261,5 +290,5 @@
           var clonedTree = (SymbolicExpressionTree)prunedTree.Clone();
           int clonedTreeSize = clonedTree.Size;
-          var prunePoints = (from node in clonedTree.IterateNodesPostfix()
+          var prunePoints = (from node in clonedTree.Root.SubTrees[0].IterateNodesPostfix()
                              from subTree in node.SubTrees
                              let subTreeSize = subTree.GetSize()
@@ -280,5 +309,5 @@
 
             double prunedQuality = evaluator.Evaluate(interpreter, clonedTree,
-        lowerEstimationLimit, upperEstimationLimit, problemData.Dataset, problemData.TargetVariable.Value, Enumerable.Range(samplesStart, samplesEnd - samplesStart));
+        lowerEstimationLimit, upperEstimationLimit, problemData.Dataset, problemData.TargetVariable.Value, rows);
             double prunedSize = clonedTree.Size;
             // deteriation in quality:
@@ -289,5 +318,5 @@
             //      R²  : newR² < origR²   (deteriation) => prefer smaller deteriation
             //      R²  : minimize: origR² / newR²
-            double qualityDeteriation = maximization ? originalQuality / prunedQuality : prunedQuality / originalQuality;
+            double qualityDeteriation = maximization ? quality.Value / prunedQuality : prunedQuality / quality.Value;
             // size of the pruned tree is always smaller than the size of the original tree
             // same change in quality => prefer pruning operation that removes a larger tree
@@ -297,4 +326,5 @@
               bestGain = gain;
               iterationBestTree = clonedTree;
+              currentQuality = prunedQuality;
             }
           }
@@ -302,4 +332,6 @@
         prunedTree = iterationBestTree;
       }
+
+      quality.Value = currentQuality;
       tree.Root = prunedTree.Root;
     }
