Index: trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/Analyzers/FixedValidationBestScaledSymbolicRegressionSolutionAnalyzer.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/Analyzers/FixedValidationBestScaledSymbolicRegressionSolutionAnalyzer.cs	(revision 4125)
+++ trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/Analyzers/FixedValidationBestScaledSymbolicRegressionSolutionAnalyzer.cs	(revision 4127)
@@ -40,4 +40,5 @@
   [StorableClass]
   public sealed class FixedValidationBestScaledSymbolicRegressionSolutionAnalyzer : SingleSuccessorOperator, ISymbolicRegressionAnalyzer {
+    private const string RandomParameterName = "Random";
     private const string SymbolicExpressionTreeParameterName = "SymbolicExpressionTree";
     private const string SymbolicExpressionTreeInterpreterParameterName = "SymbolicExpressionTreeInterpreter";
@@ -46,9 +47,6 @@
     private const string ValidationSamplesEndParameterName = "SamplesEnd";
     private const string QualityParameterName = "Quality";
-    private const string ScaledQualityParameterName = "ScaledQuality";
     private const string UpperEstimationLimitParameterName = "UpperEstimationLimit";
     private const string LowerEstimationLimitParameterName = "LowerEstimationLimit";
-    private const string AlphaParameterName = "Alpha";
-    private const string BetaParameterName = "Beta";
     private const string BestSolutionParameterName = "Best solution (validation)";
     private const string BestSolutionQualityParameterName = "Best solution quality (validation)";
@@ -59,4 +57,5 @@
     private const string BestKnownQualityParameterName = "BestKnownQuality";
     private const string GenerationsParameterName = "Generations";
+    private const string RelativeNumberOfEvaluatedSamplesParameterName = "RelativeNumberOfEvaluatedSamples";
 
     private const string TrainingMeanSquaredErrorQualityParameterName = "Mean squared error (training)";
@@ -101,16 +100,10 @@
 
     #region parameter properties
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (ILookupParameter<IRandom>)Parameters[RandomParameterName]; }
+    }
     public ScopeTreeLookupParameter<SymbolicExpressionTree> SymbolicExpressionTreeParameter {
       get { return (ScopeTreeLookupParameter<SymbolicExpressionTree>)Parameters[SymbolicExpressionTreeParameterName]; }
     }
-    public ScopeTreeLookupParameter<DoubleValue> QualityParameter {
-      get { return (ScopeTreeLookupParameter<DoubleValue>)Parameters[QualityParameterName]; }
-    }
-    public ScopeTreeLookupParameter<DoubleValue> AlphaParameter {
-      get { return (ScopeTreeLookupParameter<DoubleValue>)Parameters[AlphaParameterName]; }
-    }
-    public ScopeTreeLookupParameter<DoubleValue> BetaParameter {
-      get { return (ScopeTreeLookupParameter<DoubleValue>)Parameters[BetaParameterName]; }
-    }
     public IValueLookupParameter<ISymbolicExpressionTreeInterpreter> SymbolicExpressionTreeInterpreterParameter {
       get { return (IValueLookupParameter<ISymbolicExpressionTreeInterpreter>)Parameters[SymbolicExpressionTreeInterpreterParameterName]; }
@@ -125,4 +118,8 @@
       get { return (IValueLookupParameter<IntValue>)Parameters[ValidationSamplesEndParameterName]; }
     }
+    public IValueParameter<PercentValue> RelativeNumberOfEvaluatedSamplesParameter {
+      get { return (IValueParameter<PercentValue>)Parameters[RelativeNumberOfEvaluatedSamplesParameterName]; }
+    }
+
     public IValueLookupParameter<DoubleValue> UpperEstimationLimitParameter {
       get { return (IValueLookupParameter<DoubleValue>)Parameters[UpperEstimationLimitParameterName]; }
@@ -152,16 +149,10 @@
     #endregion
     #region properties
+    public IRandom Random {
+      get { return RandomParameter.ActualValue; }
+    }
     public ItemArray<SymbolicExpressionTree> SymbolicExpressionTree {
       get { return SymbolicExpressionTreeParameter.ActualValue; }
     }
-    public ItemArray<DoubleValue> Quality {
-      get { return QualityParameter.ActualValue; }
-    }
-    public ItemArray<DoubleValue> Alpha {
-      get { return AlphaParameter.ActualValue; }
-    }
-    public ItemArray<DoubleValue> Beta {
-      get { return BetaParameter.ActualValue; }
-    }
     public ISymbolicExpressionTreeInterpreter SymbolicExpressionTreeInterpreter {
       get { return SymbolicExpressionTreeInterpreterParameter.ActualValue; }
@@ -176,4 +167,8 @@
       get { return ValidationSamplesEndParameter.ActualValue; }
     }
+    public PercentValue RelativeNumberOfEvaluatedSamples {
+      get { return RelativeNumberOfEvaluatedSamplesParameter.Value; }
+    }
+
     public DoubleValue UpperEstimationLimit {
       get { return UpperEstimationLimitParameter.ActualValue; }
@@ -196,12 +191,12 @@
     public FixedValidationBestScaledSymbolicRegressionSolutionAnalyzer()
       : base() {
+      Parameters.Add(new LookupParameter<IRandom>(RandomParameterName, "The random generator to use."));
       Parameters.Add(new ScopeTreeLookupParameter<SymbolicExpressionTree>(SymbolicExpressionTreeParameterName, "The symbolic expression trees to analyze."));
       Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>(QualityParameterName, "The quality of the symbolic expression trees to analyze."));
-      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>(AlphaParameterName, "The alpha parameter for linear scaling."));
-      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>(BetaParameterName, "The beta parameter for linear scaling."));
       Parameters.Add(new ValueLookupParameter<ISymbolicExpressionTreeInterpreter>(SymbolicExpressionTreeInterpreterParameterName, "The interpreter that should be used for the analysis of symbolic expression trees."));
       Parameters.Add(new ValueLookupParameter<DataAnalysisProblemData>(ProblemDataParameterName, "The problem data for which the symbolic expression tree is a solution."));
       Parameters.Add(new ValueLookupParameter<IntValue>(ValidationSamplesStartParameterName, "The first index of the validation partition of the data set."));
       Parameters.Add(new ValueLookupParameter<IntValue>(ValidationSamplesEndParameterName, "The last index of the validation partition of the data set."));
+      Parameters.Add(new ValueParameter<PercentValue>(RelativeNumberOfEvaluatedSamplesParameterName, "The relative number of samples of the dataset partition, which should be randomly chosen for evaluation between the start and end index.", new PercentValue(1)));
       Parameters.Add(new ValueLookupParameter<DoubleValue>(UpperEstimationLimitParameterName, "The upper estimation limit that was set for the evaluation of the symbolic expression trees."));
       Parameters.Add(new ValueLookupParameter<DoubleValue>(LowerEstimationLimitParameterName, "The lower estimation limit that was set for the evaluation of the symbolic expression trees."));
@@ -218,41 +213,48 @@
 
     public override IOperation Apply() {
-      var alphas = Alpha;
-      var betas = Beta;
       var trees = SymbolicExpressionTree;
 
-      IEnumerable<SymbolicExpressionTree> scaledTrees;
-      if (alphas.Length == trees.Length) {
-        scaledTrees = from i in Enumerable.Range(0, trees.Length)
-                      select SymbolicRegressionSolutionLinearScaler.Scale(trees[i], alphas[i].Value, betas[i].Value);
-      } else {
-        scaledTrees = trees;
-      }
-
       string targetVariable = ProblemData.TargetVariable.Value;
+
+      // select a random subset of rows in the validation set
       int validationStart = ValidiationSamplesStart.Value;
       int validationEnd = ValidationSamplesEnd.Value;
+      uint seed = (uint)Random.Next();
+      int count = (int)((validationEnd - validationStart) * RelativeNumberOfEvaluatedSamples.Value);
+      if (count == 0) count = 1;
+      IEnumerable<int> rows = RandomEnumerable.SampleRandomNumbers(seed, validationStart, validationEnd, count);
+
       double upperEstimationLimit = UpperEstimationLimit != null ? UpperEstimationLimit.Value : double.PositiveInfinity;
       double lowerEstimationLimit = LowerEstimationLimit != null ? LowerEstimationLimit.Value : double.NegativeInfinity;
 
-      double bestValidationMse = double.MaxValue;
+      double bestValidationRSquared = -1.0;
       SymbolicExpressionTree bestTree = null;
 
-      OnlineMeanSquaredErrorEvaluator mseEvaluator = new OnlineMeanSquaredErrorEvaluator();
-      foreach (var scaledTree in scaledTrees) {
-        double validationMse = SymbolicRegressionMeanSquaredErrorEvaluator.Calculate(SymbolicExpressionTreeInterpreter, scaledTree,
+      foreach (var tree in trees) {
+        double validationRSquared = SymbolicRegressionPearsonsRSquaredEvaluator.Calculate(SymbolicExpressionTreeInterpreter, tree,
           lowerEstimationLimit, upperEstimationLimit,
           ProblemData.Dataset, targetVariable,
-         Enumerable.Range(validationStart, validationEnd - validationStart));
-
-        if (validationMse < bestValidationMse) {
-          bestValidationMse = validationMse;
-          bestTree = scaledTree;
+         rows);
+
+        if (validationRSquared > bestValidationRSquared) {
+          bestValidationRSquared = validationRSquared;
+          bestTree = tree;
         }
       }
 
-      if (BestSolutionQualityParameter.ActualValue == null || BestSolutionQualityParameter.ActualValue.Value > bestValidationMse) {
+
+      // if the best validation tree is better than the current best solution => update
+      if (BestSolutionQualityParameter.ActualValue == null || BestSolutionQualityParameter.ActualValue.Value < bestValidationRSquared) {
+        // calculate scaling parameters and validation MSE only for the best tree
+        // scale tree for solution
+        double alpha, beta;
+        double validationMSE = SymbolicRegressionScaledMeanSquaredErrorEvaluator.Calculate(SymbolicExpressionTreeInterpreter, bestTree,
+          lowerEstimationLimit, upperEstimationLimit,
+          ProblemData.Dataset, targetVariable,
+          rows, out beta, out alpha);
+
+        var scaledTree = SymbolicRegressionSolutionLinearScaler.Scale(bestTree, alpha, beta);
         var model = new SymbolicRegressionModel((ISymbolicExpressionTreeInterpreter)SymbolicExpressionTreeInterpreter.Clone(),
-          bestTree);
+          scaledTree);
         var solution = new SymbolicRegressionSolution(ProblemData, model, lowerEstimationLimit, upperEstimationLimit);
         solution.Name = BestSolutionParameterName;
@@ -260,5 +262,5 @@
 
         BestSolutionParameter.ActualValue = solution;
-        BestSolutionQualityParameter.ActualValue = new DoubleValue(bestValidationMse);
+        BestSolutionQualityParameter.ActualValue = new DoubleValue(bestValidationRSquared);
 
         BestSymbolicRegressionSolutionAnalyzer.UpdateBestSolutionResults(solution, ProblemData, Results, Generations, VariableFrequencies);
@@ -271,27 +273,14 @@
       }
       Results[BestSolutionQualityParameterName].Value = new DoubleValue(BestSolutionQualityParameter.ActualValue.Value);
-      Results[CurrentBestValidationQualityParameterName].Value = new DoubleValue(bestValidationMse);
+      Results[CurrentBestValidationQualityParameterName].Value = new DoubleValue(bestValidationRSquared);
 
       DataTable validationValues = (DataTable)Results[BestSolutionQualityValuesParameterName].Value;
       AddValue(validationValues, BestSolutionQualityParameter.ActualValue.Value, BestSolutionQualityParameterName, BestSolutionQualityParameterName);
-      AddValue(validationValues, bestValidationMse, CurrentBestValidationQualityParameterName, CurrentBestValidationQualityParameterName);
+      AddValue(validationValues, bestValidationRSquared, CurrentBestValidationQualityParameterName, CurrentBestValidationQualityParameterName);
       return base.Apply();
     }
 
     [StorableHook(HookType.AfterDeserialization)]
-    private void Initialize() {
-      if (!Parameters.ContainsKey(AlphaParameterName)) {
-        Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>(AlphaParameterName, "The alpha parameter for linear scaling."));
-      }
-      if (!Parameters.ContainsKey(BetaParameterName)) {
-        Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>(BetaParameterName, "The beta parameter for linear scaling."));
-      }
-      if (!Parameters.ContainsKey(VariableFrequenciesParameterName)) {
-        Parameters.Add(new LookupParameter<DataTable>(VariableFrequenciesParameterName, "The variable frequencies table to use for the calculation of variable impacts"));
-      }
-      if (!Parameters.ContainsKey(GenerationsParameterName)) {
-        Parameters.Add(new LookupParameter<IntValue>(GenerationsParameterName, "The number of generations calculated so far."));
-      }
-    }
+    private void Initialize() { }
 
     private static void AddValue(DataTable table, double data, string name, string description) {
Index: trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/SymbolicRegressionPearsonsRSquaredEvaluator.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/SymbolicRegressionPearsonsRSquaredEvaluator.cs	(revision 4127)
+++ trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/SymbolicRegressionPearsonsRSquaredEvaluator.cs	(revision 4127)
@@ -0,0 +1,90 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 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;
+using System.Collections.Generic;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.DataAnalysis.Evaluators;
+using HeuristicLab.Problems.DataAnalysis.Symbolic;
+
+namespace HeuristicLab.Problems.DataAnalysis.Regression.Symbolic {
+  [Item("SymbolicRegressionPearsonsRSquaredEvaluator", "Calculates the pearson r² correlation coefficient of a symbolic regression solution.")]
+  [StorableClass]
+  public class SymbolicRegressionPearsonsRSquaredEvaluator : SymbolicRegressionEvaluator {
+    private const string UpperEstimationLimitParameterName = "UpperEstimationLimit";
+    private const string LowerEstimationLimitParameterName = "LowerEstimationLimit";
+
+    #region parameter properties
+    public IValueLookupParameter<DoubleValue> UpperEstimationLimitParameter {
+      get { return (IValueLookupParameter<DoubleValue>)Parameters[UpperEstimationLimitParameterName]; }
+    }
+    public IValueLookupParameter<DoubleValue> LowerEstimationLimitParameter {
+      get { return (IValueLookupParameter<DoubleValue>)Parameters[LowerEstimationLimitParameterName]; }
+    }
+    #endregion
+    #region properties
+    public DoubleValue UpperEstimationLimit {
+      get { return UpperEstimationLimitParameter.ActualValue; }
+    }
+    public DoubleValue LowerEstimationLimit {
+      get { return LowerEstimationLimitParameter.ActualValue; }
+    }
+    #endregion
+    public SymbolicRegressionPearsonsRSquaredEvaluator()
+      : base() {
+      Parameters.Add(new ValueLookupParameter<DoubleValue>(UpperEstimationLimitParameterName, "The upper limit that should be used as cut off value for the output values of symbolic expression trees."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>(LowerEstimationLimitParameterName, "The lower limit that should be used as cut off value for the output values of symbolic expression trees."));
+    }
+
+    protected override double Evaluate(ISymbolicExpressionTreeInterpreter interpreter, SymbolicExpressionTree solution, Dataset dataset, StringValue targetVariable, IEnumerable<int> rows) {
+      double mse = Calculate(interpreter, solution, LowerEstimationLimit.Value, UpperEstimationLimit.Value, dataset, targetVariable.Value, rows);
+      return mse;
+    }
+
+    public static double Calculate(ISymbolicExpressionTreeInterpreter interpreter, SymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, Dataset dataset, string targetVariable, IEnumerable<int> rows) {
+      IEnumerable<double> estimatedValues = interpreter.GetSymbolicExpressionTreeValues(solution, dataset, rows);
+      IEnumerable<double> originalValues = dataset.GetEnumeratedVariableValues(targetVariable, rows);
+      IEnumerator<double> originalEnumerator = originalValues.GetEnumerator();
+      IEnumerator<double> estimatedEnumerator = estimatedValues.GetEnumerator();
+      OnlinePearsonsRSquaredEvaluator r2Evaluator = new OnlinePearsonsRSquaredEvaluator();
+
+      while (originalEnumerator.MoveNext() & estimatedEnumerator.MoveNext()) {
+        double estimated = estimatedEnumerator.Current;
+        double original = originalEnumerator.Current;
+        if (double.IsNaN(estimated))
+          estimated = upperEstimationLimit;
+        else
+          estimated = Math.Min(upperEstimationLimit, Math.Max(lowerEstimationLimit, estimated));
+        r2Evaluator.Add(original, estimated);
+      }
+
+      if (estimatedEnumerator.MoveNext() || originalEnumerator.MoveNext()) {
+        throw new ArgumentException("Number of elements in original and estimated enumeration doesn't match.");
+      } else {
+        return r2Evaluator.RSquared;
+      }
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/SymbolicRegressionProblem.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/SymbolicRegressionProblem.cs	(revision 4125)
+++ trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/SymbolicRegressionProblem.cs	(revision 4127)
@@ -376,7 +376,6 @@
           fixedBestValidationSolutionAnalyzer.ValidationSamplesEndParameter.Value = ValidationSamplesEnd;
           fixedBestValidationSolutionAnalyzer.BestKnownQualityParameter.ActualName = BestKnownQualityParameter.Name;
-          fixedBestValidationSolutionAnalyzer.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName;
         }
-        var bestValidationSolutionAnalyzer = analyzer as FixedValidationBestScaledSymbolicRegressionSolutionAnalyzer;
+        var bestValidationSolutionAnalyzer = analyzer as ValidationBestScaledSymbolicRegressionSolutionAnalyzer;
         if (bestValidationSolutionAnalyzer != null) {
           bestValidationSolutionAnalyzer.ProblemDataParameter.ActualName = DataAnalysisProblemDataParameter.Name;
