Index: branches/crossvalidation-2434/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression-3.4.csproj
===================================================================
--- branches/crossvalidation-2434/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression-3.4.csproj	(revision 13401)
+++ branches/crossvalidation-2434/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression-3.4.csproj	(revision 14029)
@@ -123,4 +123,7 @@
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="MultiObjective\PearsonRSquaredNestedTreeSizeEvaluator.cs" />
+    <Compile Include="MultiObjective\PearsonRSquaredNumberOfVariablesEvaluator.cs" />
+    <Compile Include="MultiObjective\PearsonRSquaredTreeComplexityEvaluator.cs" />
     <Compile Include="MultiObjective\SymbolicRegressionMultiObjectiveValidationBestSolutionAnalyzer.cs" />
     <Compile Include="Plugin.cs" />
Index: branches/crossvalidation-2434/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/PearsonRSquaredNestedTreeSizeEvaluator.cs
===================================================================
--- branches/crossvalidation-2434/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/PearsonRSquaredNestedTreeSizeEvaluator.cs	(revision 14029)
+++ branches/crossvalidation-2434/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/PearsonRSquaredNestedTreeSizeEvaluator.cs	(revision 14029)
@@ -0,0 +1,87 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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 System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Regression {
+  [Item("Pearson R² & Nested Tree size Evaluator", "Calculates the Pearson R² and the nested tree size of a symbolic regression solution.")]
+  [StorableClass]
+  public class PearsonRSquaredNestedTreeSizeEvaluator : SymbolicRegressionMultiObjectiveEvaluator {
+    [StorableConstructor]
+    protected PearsonRSquaredNestedTreeSizeEvaluator(bool deserializing) : base(deserializing) { }
+    protected PearsonRSquaredNestedTreeSizeEvaluator(PearsonRSquaredNestedTreeSizeEvaluator original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new PearsonRSquaredNestedTreeSizeEvaluator(this, cloner);
+    }
+
+    public PearsonRSquaredNestedTreeSizeEvaluator() : base() { }
+
+    public override IEnumerable<bool> Maximization { get { return new bool[2] { true, false }; } } // maximize R² & minimize nested tree size
+
+    public override IOperation InstrumentedApply() {
+      IEnumerable<int> rows = GenerateRowsToEvaluate();
+      var solution = SymbolicExpressionTreeParameter.ActualValue;
+      var problemData = ProblemDataParameter.ActualValue;
+      var interpreter = SymbolicDataAnalysisTreeInterpreterParameter.ActualValue;
+      var estimationLimits = EstimationLimitsParameter.ActualValue;
+      var applyLinearScaling = ApplyLinearScalingParameter.ActualValue.Value;
+
+      if (UseConstantOptimization) {
+        SymbolicRegressionConstantOptimizationEvaluator.OptimizeConstants(interpreter, solution, problemData, rows, applyLinearScaling, ConstantOptimizationIterations, updateVariableWeights: ConstantOptimizationUpdateVariableWeights,lowerEstimationLimit: estimationLimits.Lower, upperEstimationLimit: estimationLimits.Upper);
+      }
+
+      double[] qualities = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, solution, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, ProblemDataParameter.ActualValue, rows, ApplyLinearScalingParameter.ActualValue.Value, DecimalPlaces);
+      QualitiesParameter.ActualValue = new DoubleArray(qualities);
+      return base.InstrumentedApply();
+    }
+
+    public static double[] Calculate(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, IRegressionProblemData problemData, IEnumerable<int> rows, bool applyLinearScaling, int decimalPlaces) {
+      double r2 = SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.Calculate(interpreter, solution, lowerEstimationLimit, upperEstimationLimit, problemData, rows, applyLinearScaling);
+      if (decimalPlaces >= 0)
+        r2 = Math.Round(r2, decimalPlaces);
+      return new double[2] { r2, solution.IterateNodesPostfix().Sum(n => n.GetLength()) }; // sum of the length of the whole sub-tree for each node 
+    }
+
+    public override double[] Evaluate(IExecutionContext context, ISymbolicExpressionTree tree, IRegressionProblemData problemData, IEnumerable<int> rows) {
+      SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = context;
+      EstimationLimitsParameter.ExecutionContext = context;
+      ApplyLinearScalingParameter.ExecutionContext = context;
+      // DecimalPlaces parameter is a FixedValueParameter and doesn't need the context.
+
+      double[] quality = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, problemData, rows, ApplyLinearScalingParameter.ActualValue.Value, DecimalPlaces); 
+
+      SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = null;
+      EstimationLimitsParameter.ExecutionContext = null;
+      ApplyLinearScalingParameter.ExecutionContext = null;
+
+      return quality;
+    }
+  }
+}
Index: branches/crossvalidation-2434/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/PearsonRSquaredNumberOfVariablesEvaluator.cs
===================================================================
--- branches/crossvalidation-2434/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/PearsonRSquaredNumberOfVariablesEvaluator.cs	(revision 14029)
+++ branches/crossvalidation-2434/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/PearsonRSquaredNumberOfVariablesEvaluator.cs	(revision 14029)
@@ -0,0 +1,86 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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 System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Regression {
+  [Item("Pearson R² & Number of Variables Evaluator", "Calculates the Pearson R² and the number of used variables of a symbolic regression solution.")]
+  [StorableClass]
+  public class PearsonRSquaredNumberOfVariablesEvaluator : SymbolicRegressionMultiObjectiveEvaluator {
+    [StorableConstructor]
+    protected PearsonRSquaredNumberOfVariablesEvaluator(bool deserializing) : base(deserializing) { }
+    protected PearsonRSquaredNumberOfVariablesEvaluator(PearsonRSquaredNumberOfVariablesEvaluator original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new PearsonRSquaredNumberOfVariablesEvaluator(this, cloner);
+    }
+
+    public PearsonRSquaredNumberOfVariablesEvaluator() : base() { }
+
+    public override IEnumerable<bool> Maximization { get { return new bool[2] { true, false }; } } // maximize R² and minimize the number of variables
+
+    public override IOperation InstrumentedApply() {
+      IEnumerable<int> rows = GenerateRowsToEvaluate();
+      var solution = SymbolicExpressionTreeParameter.ActualValue;
+      var problemData = ProblemDataParameter.ActualValue;
+      var interpreter = SymbolicDataAnalysisTreeInterpreterParameter.ActualValue;
+      var estimationLimits = EstimationLimitsParameter.ActualValue;
+      var applyLinearScaling = ApplyLinearScalingParameter.ActualValue.Value;
+
+      if (UseConstantOptimization) {
+        SymbolicRegressionConstantOptimizationEvaluator.OptimizeConstants(interpreter, solution, problemData, rows, applyLinearScaling, ConstantOptimizationIterations, updateVariableWeights: ConstantOptimizationUpdateVariableWeights, lowerEstimationLimit: estimationLimits.Lower, upperEstimationLimit: estimationLimits.Upper);
+      }
+      double[] qualities = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, solution, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, ProblemDataParameter.ActualValue, rows, ApplyLinearScalingParameter.ActualValue.Value, DecimalPlaces);
+      QualitiesParameter.ActualValue = new DoubleArray(qualities);
+      return base.InstrumentedApply();
+    }
+
+    public static double[] Calculate(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, IRegressionProblemData problemData, IEnumerable<int> rows, bool applyLinearScaling, int decimalPlaces) {
+      double r2 = SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.Calculate(interpreter, solution, lowerEstimationLimit, upperEstimationLimit, problemData, rows, applyLinearScaling);
+      if (decimalPlaces >= 0)
+        r2 = Math.Round(r2, decimalPlaces);
+      return new double[2] { r2, solution.IterateNodesPostfix().OfType<VariableTreeNode>().Count() }; // count the number of variables
+    }
+
+    public override double[] Evaluate(IExecutionContext context, ISymbolicExpressionTree tree, IRegressionProblemData problemData, IEnumerable<int> rows) {
+      SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = context;
+      EstimationLimitsParameter.ExecutionContext = context;
+      ApplyLinearScalingParameter.ExecutionContext = context;
+      // DecimalPlaces parameter is a FixedValueParameter and doesn't need the context.
+
+      double[] quality = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, problemData, rows, ApplyLinearScalingParameter.ActualValue.Value, DecimalPlaces);
+
+      SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = null;
+      EstimationLimitsParameter.ExecutionContext = null;
+      ApplyLinearScalingParameter.ExecutionContext = null;
+
+      return quality;
+    }
+  }
+}
Index: branches/crossvalidation-2434/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/PearsonRSquaredTreeComplexityEvaluator.cs
===================================================================
--- branches/crossvalidation-2434/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/PearsonRSquaredTreeComplexityEvaluator.cs	(revision 14029)
+++ branches/crossvalidation-2434/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/PearsonRSquaredTreeComplexityEvaluator.cs	(revision 14029)
@@ -0,0 +1,85 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Regression {
+  [Item("Pearson R² & Tree Complexity Evaluator", "Calculates the Pearson R² and the tree complexity of a symbolic regression solution.")]
+  [StorableClass]
+  public class PearsonRSquaredTreeComplexityEvaluator : SymbolicRegressionMultiObjectiveEvaluator {
+    [StorableConstructor]
+    protected PearsonRSquaredTreeComplexityEvaluator(bool deserializing) : base(deserializing) { }
+    protected PearsonRSquaredTreeComplexityEvaluator(PearsonRSquaredTreeComplexityEvaluator original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new PearsonRSquaredTreeComplexityEvaluator(this, cloner);
+    }
+
+    public PearsonRSquaredTreeComplexityEvaluator() : base() { }
+
+    public override IEnumerable<bool> Maximization { get { return new bool[2] { true, false }; } } // maximize R² and minimize model complexity 
+
+    public override IOperation InstrumentedApply() {
+      IEnumerable<int> rows = GenerateRowsToEvaluate();
+      var solution = SymbolicExpressionTreeParameter.ActualValue;
+      var problemData = ProblemDataParameter.ActualValue;
+      var interpreter = SymbolicDataAnalysisTreeInterpreterParameter.ActualValue;
+      var estimationLimits = EstimationLimitsParameter.ActualValue;
+      var applyLinearScaling = ApplyLinearScalingParameter.ActualValue.Value;
+
+      if (UseConstantOptimization) {
+        SymbolicRegressionConstantOptimizationEvaluator.OptimizeConstants(interpreter, solution, problemData, rows, applyLinearScaling, ConstantOptimizationIterations, updateVariableWeights: ConstantOptimizationUpdateVariableWeights, lowerEstimationLimit: estimationLimits.Lower, upperEstimationLimit: estimationLimits.Upper);
+      }
+      double[] qualities = Calculate(interpreter, solution, estimationLimits.Lower, estimationLimits.Upper, problemData, rows, applyLinearScaling, DecimalPlaces);
+      QualitiesParameter.ActualValue = new DoubleArray(qualities);
+      return base.InstrumentedApply();
+    }
+
+    public static double[] Calculate(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, IRegressionProblemData problemData, IEnumerable<int> rows, bool applyLinearScaling, int decimalPlaces) {
+      double r2 = SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.Calculate(interpreter, solution, lowerEstimationLimit, upperEstimationLimit, problemData, rows, applyLinearScaling);
+      if (decimalPlaces >= 0)
+        r2 = Math.Round(r2, decimalPlaces);
+      return new double[2] { r2, SymbolicDataAnalysisModelComplexityCalculator.CalculateComplexity(solution) };
+    }
+
+    public override double[] Evaluate(IExecutionContext context, ISymbolicExpressionTree tree, IRegressionProblemData problemData, IEnumerable<int> rows) {
+      SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = context;
+      EstimationLimitsParameter.ExecutionContext = context;
+      ApplyLinearScalingParameter.ExecutionContext = context;
+      // DecimalPlaces parameter is a FixedValueParameter and doesn't need the context.
+
+      double[] quality = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, problemData, rows, ApplyLinearScalingParameter.ActualValue.Value, DecimalPlaces);
+
+      SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = null;
+      EstimationLimitsParameter.ExecutionContext = null;
+      ApplyLinearScalingParameter.ExecutionContext = null;
+
+      return quality;
+    }
+  }
+}
Index: branches/crossvalidation-2434/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/SymbolicRegressionMultiObjectiveEvaluator.cs
===================================================================
--- branches/crossvalidation-2434/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/SymbolicRegressionMultiObjectiveEvaluator.cs	(revision 13401)
+++ branches/crossvalidation-2434/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/SymbolicRegressionMultiObjectiveEvaluator.cs	(revision 14029)
@@ -22,7 +22,51 @@
 
 using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Regression {
+  [StorableClass]
   public abstract class SymbolicRegressionMultiObjectiveEvaluator : SymbolicDataAnalysisMultiObjectiveEvaluator<IRegressionProblemData>, ISymbolicRegressionMultiObjectiveEvaluator {
+    private const string DecimalPlacesParameterName = "Decimal Places";
+    private const string UseConstantOptimizationParameterName = "Use constant optimization";
+    private const string ConstantOptimizationIterationsParameterName = "Constant optimization iterations";
+
+    private const string ConstantOptimizationUpdateVariableWeightsParameterName =
+      "Constant optimization update variable weights";
+
+    public IFixedValueParameter<IntValue> DecimalPlacesParameter {
+      get { return (IFixedValueParameter<IntValue>)Parameters[DecimalPlacesParameterName]; }
+    }
+    public IFixedValueParameter<BoolValue> UseConstantOptimizationParameter {
+      get { return (IFixedValueParameter<BoolValue>)Parameters[UseConstantOptimizationParameterName]; }
+    }
+
+    public IFixedValueParameter<IntValue> ConstantOptimizationIterationsParameter {
+      get { return (IFixedValueParameter<IntValue>)Parameters[ConstantOptimizationIterationsParameterName]; }
+    }
+
+    public IFixedValueParameter<BoolValue> ConstantOptimizationUpdateVariableWeightsParameter {
+      get { return (IFixedValueParameter<BoolValue>)Parameters[ConstantOptimizationUpdateVariableWeightsParameterName]; }
+    }
+
+    public int DecimalPlaces {
+      get { return DecimalPlacesParameter.Value.Value; }
+      set { DecimalPlacesParameter.Value.Value = value; }
+    }
+    public bool UseConstantOptimization {
+      get { return UseConstantOptimizationParameter.Value.Value; }
+      set { UseConstantOptimizationParameter.Value.Value = value; }
+    }
+    public int ConstantOptimizationIterations {
+      get { return ConstantOptimizationIterationsParameter.Value.Value; }
+      set { ConstantOptimizationIterationsParameter.Value.Value = value; }
+    }
+    public bool ConstantOptimizationUpdateVariableWeights {
+      get { return ConstantOptimizationUpdateVariableWeightsParameter.Value.Value; }
+      set { ConstantOptimizationUpdateVariableWeightsParameter.Value.Value = value; }
+    }
+
     [StorableConstructor]
     protected SymbolicRegressionMultiObjectiveEvaluator(bool deserializing) : base(deserializing) { }
@@ -31,5 +75,27 @@
     }
 
-    protected SymbolicRegressionMultiObjectiveEvaluator() : base() { }
+    protected SymbolicRegressionMultiObjectiveEvaluator()
+      : base() {
+      Parameters.Add(new FixedValueParameter<IntValue>(DecimalPlacesParameterName, "The number of decimal places used for rounding the quality values.", new IntValue(5)) { Hidden = true });
+      Parameters.Add(new FixedValueParameter<BoolValue>(UseConstantOptimizationParameterName, "", new BoolValue(false)));
+      Parameters.Add(new FixedValueParameter<IntValue>(ConstantOptimizationIterationsParameterName, "The number of iterations constant optimization should be applied.", new IntValue(5)));
+      Parameters.Add(new FixedValueParameter<BoolValue>(ConstantOptimizationUpdateVariableWeightsParameterName, "Determines if the variable weights in the tree should be optimized during constant optimization.", new BoolValue(true)) { Hidden = true });
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      if (!Parameters.ContainsKey(UseConstantOptimizationParameterName)) {
+        Parameters.Add(new FixedValueParameter<BoolValue>(UseConstantOptimizationParameterName, "", new BoolValue(false)));
+      }
+      if (!Parameters.ContainsKey(DecimalPlacesParameterName)) {
+        Parameters.Add(new FixedValueParameter<IntValue>(DecimalPlacesParameterName, "The number of decimal places used for rounding the quality values.", new IntValue(-1)) { Hidden = true });
+      }
+      if (!Parameters.ContainsKey(ConstantOptimizationIterationsParameterName)) {
+        Parameters.Add(new FixedValueParameter<IntValue>(ConstantOptimizationIterationsParameterName, "The number of iterations constant optimization should be applied.", new IntValue(5)));
+      }
+      if (!Parameters.ContainsKey(ConstantOptimizationUpdateVariableWeightsParameterName)) {
+        Parameters.Add(new FixedValueParameter<BoolValue>(ConstantOptimizationUpdateVariableWeightsParameterName, "Determines if the variable weights in the tree should be optimized during constant optimization.", new BoolValue(true)));
+      }
+    }
   }
 }
Index: branches/crossvalidation-2434/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/SymbolicRegressionMultiObjectiveMeanSquaredErrorTreeSizeEvaluator.cs
===================================================================
--- branches/crossvalidation-2434/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/SymbolicRegressionMultiObjectiveMeanSquaredErrorTreeSizeEvaluator.cs	(revision 13401)
+++ branches/crossvalidation-2434/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/SymbolicRegressionMultiObjectiveMeanSquaredErrorTreeSizeEvaluator.cs	(revision 14029)
@@ -20,4 +20,5 @@
 #endregion
 
+using System;
 using System.Collections.Generic;
 using HeuristicLab.Common;
@@ -47,25 +48,25 @@
       IEnumerable<int> rows = GenerateRowsToEvaluate();
       var solution = SymbolicExpressionTreeParameter.ActualValue;
-      double[] qualities = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, solution, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, ProblemDataParameter.ActualValue, rows, ApplyLinearScalingParameter.ActualValue.Value);
+      var problemData = ProblemDataParameter.ActualValue;
+      var interpreter = SymbolicDataAnalysisTreeInterpreterParameter.ActualValue;
+      var estimationLimits = EstimationLimitsParameter.ActualValue;
+      var applyLinearScaling = ApplyLinearScalingParameter.ActualValue.Value;
+
+      if (UseConstantOptimization) {
+        SymbolicRegressionConstantOptimizationEvaluator.OptimizeConstants(interpreter, solution, problemData, rows, applyLinearScaling, ConstantOptimizationIterations, updateVariableWeights: ConstantOptimizationUpdateVariableWeights, lowerEstimationLimit: estimationLimits.Lower, upperEstimationLimit: estimationLimits.Upper);
+      }
+
+      double[] qualities = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, solution, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, ProblemDataParameter.ActualValue, rows, ApplyLinearScalingParameter.ActualValue.Value, DecimalPlaces);
       QualitiesParameter.ActualValue = new DoubleArray(qualities);
       return base.InstrumentedApply();
     }
 
-    public static double[] Calculate(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, IRegressionProblemData problemData, IEnumerable<int> rows, bool applyLinearScaling) {
-      IEnumerable<double> estimatedValues = interpreter.GetSymbolicExpressionTreeValues(solution, problemData.Dataset, rows);
-      IEnumerable<double> targetValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows);
-      OnlineCalculatorError errorState;
+    public static double[] Calculate(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, IRegressionProblemData problemData, IEnumerable<int> rows, bool applyLinearScaling, int decimalPlaces) {
+      var mse = SymbolicRegressionSingleObjectiveMeanSquaredErrorEvaluator.Calculate(interpreter, solution, lowerEstimationLimit,
+        upperEstimationLimit, problemData, rows, applyLinearScaling);
 
-      double mse;
-      if (applyLinearScaling) {
-        var mseCalculator = new OnlineMeanSquaredErrorCalculator();
-        CalculateWithScaling(targetValues, estimatedValues, lowerEstimationLimit, upperEstimationLimit, mseCalculator, problemData.Dataset.Rows);
-        errorState = mseCalculator.ErrorState;
-        mse = mseCalculator.MeanSquaredError;
-      } else {
-        IEnumerable<double> boundedEstimatedValues = estimatedValues.LimitToRange(lowerEstimationLimit, upperEstimationLimit);
-        mse = OnlineMeanSquaredErrorCalculator.Calculate(targetValues, boundedEstimatedValues, out errorState);
-      }
-      if (errorState != OnlineCalculatorError.None) mse = double.NaN;
+      if (decimalPlaces >= 0)
+        mse = Math.Round(mse, decimalPlaces);
+
       return new double[2] { mse, solution.Length };
     }
@@ -76,5 +77,5 @@
       ApplyLinearScalingParameter.ExecutionContext = context;
 
-      double[] quality = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, problemData, rows, ApplyLinearScalingParameter.ActualValue.Value);
+      double[] quality = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, problemData, rows, ApplyLinearScalingParameter.ActualValue.Value, DecimalPlaces);
 
       SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = null;
Index: branches/crossvalidation-2434/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/SymbolicRegressionMultiObjectivePearsonRSquaredTreeSizeEvaluator.cs
===================================================================
--- branches/crossvalidation-2434/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/SymbolicRegressionMultiObjectivePearsonRSquaredTreeSizeEvaluator.cs	(revision 13401)
+++ branches/crossvalidation-2434/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/SymbolicRegressionMultiObjectivePearsonRSquaredTreeSizeEvaluator.cs	(revision 14029)
@@ -20,4 +20,5 @@
 #endregion
 
+using System;
 using System.Collections.Generic;
 using HeuristicLab.Common;
@@ -47,27 +48,22 @@
       IEnumerable<int> rows = GenerateRowsToEvaluate();
       var solution = SymbolicExpressionTreeParameter.ActualValue;
-      double[] qualities = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, solution, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, ProblemDataParameter.ActualValue, rows, ApplyLinearScalingParameter.ActualValue.Value);
+      var problemData = ProblemDataParameter.ActualValue;
+      var interpreter = SymbolicDataAnalysisTreeInterpreterParameter.ActualValue;
+      var estimationLimits = EstimationLimitsParameter.ActualValue;
+      var applyLinearScaling = ApplyLinearScalingParameter.ActualValue.Value;
+
+      if (UseConstantOptimization) {
+        SymbolicRegressionConstantOptimizationEvaluator.OptimizeConstants(interpreter, solution, problemData, rows, applyLinearScaling, ConstantOptimizationIterations, updateVariableWeights: ConstantOptimizationUpdateVariableWeights, lowerEstimationLimit: estimationLimits.Lower, upperEstimationLimit: estimationLimits.Upper);
+      }
+      double[] qualities = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, solution, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, ProblemDataParameter.ActualValue, rows, ApplyLinearScalingParameter.ActualValue.Value, DecimalPlaces);
       QualitiesParameter.ActualValue = new DoubleArray(qualities);
       return base.InstrumentedApply();
     }
 
-    public static double[] Calculate(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, IRegressionProblemData problemData, IEnumerable<int> rows, bool applyLinearScaling) {
-      IEnumerable<double> estimatedValues = interpreter.GetSymbolicExpressionTreeValues(solution, problemData.Dataset, rows);
-      IEnumerable<double> targetValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows);
-      OnlineCalculatorError errorState;
-
-      double r;
-      if (applyLinearScaling) {
-        var rCalculator = new OnlinePearsonsRCalculator();
-        CalculateWithScaling(targetValues, estimatedValues, lowerEstimationLimit, upperEstimationLimit, rCalculator, problemData.Dataset.Rows);
-        errorState = rCalculator.ErrorState;
-        r = rCalculator.R;
-      } else {
-        IEnumerable<double> boundedEstimatedValues = estimatedValues.LimitToRange(lowerEstimationLimit, upperEstimationLimit);
-        r = OnlinePearsonsRCalculator.Calculate(targetValues, boundedEstimatedValues, out errorState);
-      }
-
-      if (errorState != OnlineCalculatorError.None) r = double.NaN;
-      return new double[2] { r*r, solution.Length };
+    public static double[] Calculate(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, IRegressionProblemData problemData, IEnumerable<int> rows, bool applyLinearScaling, int decimalPlaces) {
+      double r2 = SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.Calculate(interpreter, solution, lowerEstimationLimit, upperEstimationLimit, problemData, rows, applyLinearScaling);
+      if (decimalPlaces >= 0)
+        r2 = Math.Round(r2, decimalPlaces);
+      return new double[2] { r2, solution.Length };
     }
 
@@ -77,5 +73,5 @@
       ApplyLinearScalingParameter.ExecutionContext = context;
 
-      double[] quality = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, problemData, rows, ApplyLinearScalingParameter.ActualValue.Value);
+      double[] quality = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, problemData, rows, ApplyLinearScalingParameter.ActualValue.Value, DecimalPlaces);
 
       SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = null;
Index: branches/crossvalidation-2434/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/SymbolicRegressionMultiObjectiveTrainingBestSolutionAnalyzer.cs
===================================================================
--- branches/crossvalidation-2434/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/SymbolicRegressionMultiObjectiveTrainingBestSolutionAnalyzer.cs	(revision 13401)
+++ branches/crossvalidation-2434/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/SymbolicRegressionMultiObjectiveTrainingBestSolutionAnalyzer.cs	(revision 14029)
@@ -20,7 +20,12 @@
 #endregion
 
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Analysis;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
+using HeuristicLab.Data;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Optimization;
 using HeuristicLab.Parameters;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
@@ -37,4 +42,7 @@
     private const string SymbolicDataAnalysisTreeInterpreterParameterName = "SymbolicDataAnalysisTreeInterpreter";
     private const string EstimationLimitsParameterName = "EstimationLimits";
+    private const string MaximumSymbolicExpressionTreeLengthParameterName = "MaximumSymbolicExpressionTreeLength";
+    private const string ValidationPartitionParameterName = "ValidationPartition";
+
     #region parameter properties
     public ILookupParameter<IRegressionProblemData> ProblemDataParameter {
@@ -47,4 +55,11 @@
       get { return (IValueLookupParameter<DoubleLimit>)Parameters[EstimationLimitsParameterName]; }
     }
+    public ILookupParameter<IntValue> MaximumSymbolicExpressionTreeLengthParameter {
+      get { return (ILookupParameter<IntValue>)Parameters[MaximumSymbolicExpressionTreeLengthParameterName]; }
+    }
+
+    public IValueLookupParameter<IntRange> ValidationPartitionParameter {
+      get { return (IValueLookupParameter<IntRange>)Parameters[ValidationPartitionParameterName]; }
+    }
     #endregion
 
@@ -54,7 +69,17 @@
     public SymbolicRegressionMultiObjectiveTrainingBestSolutionAnalyzer()
       : base() {
-      Parameters.Add(new LookupParameter<IRegressionProblemData>(ProblemDataParameterName, "The problem data for the symbolic regression solution."));
-      Parameters.Add(new LookupParameter<ISymbolicDataAnalysisExpressionTreeInterpreter>(SymbolicDataAnalysisTreeInterpreterParameterName, "The symbolic data analysis tree interpreter for the symbolic expression tree."));
-      Parameters.Add(new ValueLookupParameter<DoubleLimit>(EstimationLimitsParameterName, "The lower and upper limit for the estimated values produced by the symbolic regression model."));
+      Parameters.Add(new LookupParameter<IRegressionProblemData>(ProblemDataParameterName, "The problem data for the symbolic regression solution.") { Hidden = true });
+      Parameters.Add(new LookupParameter<ISymbolicDataAnalysisExpressionTreeInterpreter>(SymbolicDataAnalysisTreeInterpreterParameterName, "The symbolic data analysis tree interpreter for the symbolic expression tree.") { Hidden = true });
+      Parameters.Add(new ValueLookupParameter<DoubleLimit>(EstimationLimitsParameterName, "The lower and upper limit for the estimated values produced by the symbolic regression model.") { Hidden = true });
+      Parameters.Add(new LookupParameter<IntValue>(MaximumSymbolicExpressionTreeLengthParameterName, "Maximal length of the symbolic expression.") { Hidden = true });
+      Parameters.Add(new ValueLookupParameter<IntRange>(ValidationPartitionParameterName, "The validation partition."));
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      if (!Parameters.ContainsKey(MaximumSymbolicExpressionTreeLengthParameterName))
+        Parameters.Add(new LookupParameter<IntValue>(MaximumSymbolicExpressionTreeLengthParameterName, "Maximal length of the symbolic expression.") { Hidden = true });
+      if (!Parameters.ContainsKey(ValidationPartitionParameterName))
+        Parameters.Add(new ValueLookupParameter<IntRange>(ValidationPartitionParameterName, "The validation partition."));
     }
 
@@ -64,8 +89,66 @@
 
     protected override ISymbolicRegressionSolution CreateSolution(ISymbolicExpressionTree bestTree, double[] bestQuality) {
-      var model = new SymbolicRegressionModel((ISymbolicExpressionTree)bestTree.Clone(), SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper);
+      var model = new SymbolicRegressionModel(ProblemDataParameter.ActualValue.TargetVariable, (ISymbolicExpressionTree)bestTree.Clone(), SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper);
       if (ApplyLinearScalingParameter.ActualValue.Value) model.Scale(ProblemDataParameter.ActualValue);
       return new SymbolicRegressionSolution(model, (IRegressionProblemData)ProblemDataParameter.ActualValue.Clone());
     }
+
+    public override IOperation Apply() {
+      var operation = base.Apply();
+      var paretoFront = TrainingBestSolutionsParameter.ActualValue;
+
+      IResult result;
+      ScatterPlot qualityToTreeSize;
+      if (!ResultCollection.TryGetValue("Pareto Front Analysis", out result)) {
+        qualityToTreeSize = new ScatterPlot("Quality vs Tree Size", "");
+        qualityToTreeSize.VisualProperties.XAxisMinimumAuto = false;
+        qualityToTreeSize.VisualProperties.XAxisMaximumAuto = false;
+        qualityToTreeSize.VisualProperties.YAxisMinimumAuto = false;
+        qualityToTreeSize.VisualProperties.YAxisMaximumAuto = false;
+
+        qualityToTreeSize.VisualProperties.XAxisMinimumFixedValue = 0;
+        qualityToTreeSize.VisualProperties.XAxisMaximumFixedValue = MaximumSymbolicExpressionTreeLengthParameter.ActualValue.Value;
+        qualityToTreeSize.VisualProperties.YAxisMinimumFixedValue = 0;
+        qualityToTreeSize.VisualProperties.YAxisMaximumFixedValue = 2;
+        ResultCollection.Add(new Result("Pareto Front Analysis", qualityToTreeSize));
+      } else {
+        qualityToTreeSize = (ScatterPlot)result.Value;
+      }
+
+
+      int previousTreeLength = -1;
+      var sizeParetoFront = new LinkedList<ISymbolicRegressionSolution>();
+      foreach (var solution in paretoFront.OrderBy(s => s.Model.SymbolicExpressionTree.Length)) {
+        int treeLength = solution.Model.SymbolicExpressionTree.Length;
+        if (!sizeParetoFront.Any()) sizeParetoFront.AddLast(solution);
+        if (solution.TrainingNormalizedMeanSquaredError < sizeParetoFront.Last.Value.TrainingNormalizedMeanSquaredError) {
+          if (treeLength == previousTreeLength)
+            sizeParetoFront.RemoveLast();
+          sizeParetoFront.AddLast(solution);
+        }
+        previousTreeLength = treeLength;
+      }
+
+      qualityToTreeSize.Rows.Clear();
+      var trainingRow = new ScatterPlotDataRow("Training NMSE", "", sizeParetoFront.Select(x => new Point2D<double>(x.Model.SymbolicExpressionTree.Length, x.TrainingNormalizedMeanSquaredError)));
+      trainingRow.VisualProperties.PointSize = 8;
+      qualityToTreeSize.Rows.Add(trainingRow);
+
+      var validationPartition = ValidationPartitionParameter.ActualValue;
+      if (validationPartition.Size != 0) {
+        var problemData = ProblemDataParameter.ActualValue;
+        var validationIndizes = Enumerable.Range(validationPartition.Start, validationPartition.Size).ToList();
+        var targetValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, validationIndizes).ToList();
+        OnlineCalculatorError error;
+        var validationRow = new ScatterPlotDataRow("Validation NMSE", "",
+          sizeParetoFront.Select(x => new Point2D<double>(x.Model.SymbolicExpressionTree.Length,
+          OnlineNormalizedMeanSquaredErrorCalculator.Calculate(targetValues, x.GetEstimatedValues(validationIndizes), out error))));
+        validationRow.VisualProperties.PointSize = 7;
+        qualityToTreeSize.Rows.Add(validationRow);
+      }
+
+      return operation;
+    }
+
   }
 }
Index: branches/crossvalidation-2434/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/SymbolicRegressionMultiObjectiveValidationBestSolutionAnalyzer.cs
===================================================================
--- branches/crossvalidation-2434/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/SymbolicRegressionMultiObjectiveValidationBestSolutionAnalyzer.cs	(revision 13401)
+++ branches/crossvalidation-2434/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/SymbolicRegressionMultiObjectiveValidationBestSolutionAnalyzer.cs	(revision 14029)
@@ -54,5 +54,5 @@
 
     protected override ISymbolicRegressionSolution CreateSolution(ISymbolicExpressionTree bestTree, double[] bestQuality) {
-      var model = new SymbolicRegressionModel((ISymbolicExpressionTree)bestTree.Clone(), SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper);
+      var model = new SymbolicRegressionModel(ProblemDataParameter.ActualValue.TargetVariable, (ISymbolicExpressionTree)bestTree.Clone(), SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper);
       if (ApplyLinearScalingParameter.ActualValue.Value) model.Scale(ProblemDataParameter.ActualValue);
       return new SymbolicRegressionSolution(model, (IRegressionProblemData)ProblemDataParameter.ActualValue.Clone());
Index: branches/crossvalidation-2434/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/Plugin.cs.frame
===================================================================
--- branches/crossvalidation-2434/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/Plugin.cs.frame	(revision 13401)
+++ branches/crossvalidation-2434/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/Plugin.cs.frame	(revision 14029)
@@ -26,5 +26,5 @@
 
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Regression {
-  [Plugin("HeuristicLab.Problems.DataAnalysis.Symbolic.Regression","Provides classes to perform symbolic regression (single- or multiobjective).", "3.4.8.$WCREV$")]
+  [Plugin("HeuristicLab.Problems.DataAnalysis.Symbolic.Regression","Provides classes to perform symbolic regression (single- or multiobjective).", "3.4.9.$WCREV$")]
   [PluginFile("HeuristicLab.Problems.DataAnalysis.Symbolic.Regression-3.4.dll", PluginFileType.Assembly)]
   [PluginDependency("HeuristicLab.ALGLIB", "3.7.0")]
Index: branches/crossvalidation-2434/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/Properties/AssemblyInfo.cs.frame
===================================================================
--- branches/crossvalidation-2434/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/Properties/AssemblyInfo.cs.frame	(revision 13401)
+++ branches/crossvalidation-2434/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/Properties/AssemblyInfo.cs.frame	(revision 14029)
@@ -53,3 +53,3 @@
 // by using the '*' as shown below:
 [assembly: AssemblyVersion("3.4.0.0")]
-[assembly: AssemblyFileVersion("3.4.8.$WCREV$")]
+[assembly: AssemblyFileVersion("3.4.9.$WCREV$")]
Index: branches/crossvalidation-2434/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionConstantOptimizationEvaluator.cs
===================================================================
--- branches/crossvalidation-2434/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionConstantOptimizationEvaluator.cs	(revision 13401)
+++ branches/crossvalidation-2434/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionConstantOptimizationEvaluator.cs	(revision 14029)
@@ -40,4 +40,5 @@
     private const string ConstantOptimizationRowsPercentageParameterName = "ConstantOptimizationRowsPercentage";
     private const string UpdateConstantsInTreeParameterName = "UpdateConstantsInSymbolicExpressionTree";
+    private const string UpdateVariableWeightsParameterName = "Update Variable Weights";
 
     public IFixedValueParameter<IntValue> ConstantOptimizationIterationsParameter {
@@ -56,4 +57,8 @@
       get { return (IFixedValueParameter<BoolValue>)Parameters[UpdateConstantsInTreeParameterName]; }
     }
+    public IFixedValueParameter<BoolValue> UpdateVariableWeightsParameter {
+      get { return (IFixedValueParameter<BoolValue>)Parameters[UpdateVariableWeightsParameterName]; }
+    }
+
 
     public IntValue ConstantOptimizationIterations {
@@ -72,4 +77,9 @@
       get { return UpdateConstantsInTreeParameter.Value.Value; }
       set { UpdateConstantsInTreeParameter.Value.Value = value; }
+    }
+
+    public bool UpdateVariableWeights {
+      get { return UpdateVariableWeightsParameter.Value.Value; }
+      set { UpdateVariableWeightsParameter.Value.Value = value; }
     }
 
@@ -86,8 +96,9 @@
       : base() {
       Parameters.Add(new FixedValueParameter<IntValue>(ConstantOptimizationIterationsParameterName, "Determines how many iterations should be calculated while optimizing the constant of a symbolic expression tree (0 indicates other or default stopping criterion).", new IntValue(10), true));
-      Parameters.Add(new FixedValueParameter<DoubleValue>(ConstantOptimizationImprovementParameterName, "Determines the relative improvement which must be achieved in the constant optimization to continue with it (0 indicates other or default stopping criterion).", new DoubleValue(0), true));
+      Parameters.Add(new FixedValueParameter<DoubleValue>(ConstantOptimizationImprovementParameterName, "Determines the relative improvement which must be achieved in the constant optimization to continue with it (0 indicates other or default stopping criterion).", new DoubleValue(0), true) { Hidden = true });
       Parameters.Add(new FixedValueParameter<PercentValue>(ConstantOptimizationProbabilityParameterName, "Determines the probability that the constants are optimized", new PercentValue(1), true));
       Parameters.Add(new FixedValueParameter<PercentValue>(ConstantOptimizationRowsPercentageParameterName, "Determines the percentage of the rows which should be used for constant optimization", new PercentValue(1), true));
-      Parameters.Add(new FixedValueParameter<BoolValue>(UpdateConstantsInTreeParameterName, "Determines if the constants in the tree should be overwritten by the optimized constants.", new BoolValue(true)));
+      Parameters.Add(new FixedValueParameter<BoolValue>(UpdateConstantsInTreeParameterName, "Determines if the constants in the tree should be overwritten by the optimized constants.", new BoolValue(true)) { Hidden = true });
+      Parameters.Add(new FixedValueParameter<BoolValue>(UpdateVariableWeightsParameterName, "Determines if the variable weights in the tree should be  optimized.", new BoolValue(true)) { Hidden = true });
     }
 
@@ -100,4 +111,6 @@
       if (!Parameters.ContainsKey(UpdateConstantsInTreeParameterName))
         Parameters.Add(new FixedValueParameter<BoolValue>(UpdateConstantsInTreeParameterName, "Determines if the constants in the tree should be overwritten by the optimized constants.", new BoolValue(true)));
+      if (!Parameters.ContainsKey(UpdateVariableWeightsParameterName))
+        Parameters.Add(new FixedValueParameter<BoolValue>(UpdateVariableWeightsParameterName, "Determines if the variable weights in the tree should be  optimized.", new BoolValue(true)));
     }
 
@@ -108,6 +121,5 @@
         IEnumerable<int> constantOptimizationRows = GenerateRowsToEvaluate(ConstantOptimizationRowsPercentage.Value);
         quality = OptimizeConstants(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, solution, ProblemDataParameter.ActualValue,
-           constantOptimizationRows, ApplyLinearScalingParameter.ActualValue.Value, ConstantOptimizationIterations.Value,
-           EstimationLimitsParameter.ActualValue.Upper, EstimationLimitsParameter.ActualValue.Lower, UpdateConstantsInTree);
+           constantOptimizationRows, ApplyLinearScalingParameter.ActualValue.Value, ConstantOptimizationIterations.Value, updateVariableWeights: UpdateVariableWeights, lowerEstimationLimit: EstimationLimitsParameter.ActualValue.Lower, upperEstimationLimit: EstimationLimitsParameter.ActualValue.Upper, updateConstantsInTree: UpdateConstantsInTree);
 
         if (ConstantOptimizationRowsPercentage.Value != RelativeNumberOfEvaluatedSamplesParameter.ActualValue.Value) {
@@ -164,6 +176,5 @@
 
 
-    public static double OptimizeConstants(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree tree, IRegressionProblemData problemData,
-      IEnumerable<int> rows, bool applyLinearScaling, int maxIterations, double upperEstimationLimit = double.MaxValue, double lowerEstimationLimit = double.MinValue, bool updateConstantsInTree = true) {
+    public static double OptimizeConstants(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree tree, IRegressionProblemData problemData, IEnumerable<int> rows, bool applyLinearScaling, int maxIterations, bool updateVariableWeights = true, double lowerEstimationLimit = double.MinValue, double upperEstimationLimit = double.MaxValue, bool updateConstantsInTree = true) {
 
       List<AutoDiff.Variable> variables = new List<AutoDiff.Variable>();
@@ -172,17 +183,21 @@
 
       AutoDiff.Term func;
-      if (!TryTransformToAutoDiff(tree.Root.GetSubtree(0), variables, parameters, variableNames, out func))
+      if (!TryTransformToAutoDiff(tree.Root.GetSubtree(0), variables, parameters, variableNames, updateVariableWeights, out func))
         throw new NotSupportedException("Could not optimize constants of symbolic expression tree due to not supported symbols used in the tree.");
       if (variableNames.Count == 0) return 0.0;
 
-      AutoDiff.IParametricCompiledTerm compiledFunc = AutoDiff.TermUtils.Compile(func, variables.ToArray(), parameters.ToArray());
-
-      List<SymbolicExpressionTreeTerminalNode> terminalNodes = tree.Root.IterateNodesPrefix().OfType<SymbolicExpressionTreeTerminalNode>().ToList();
+      AutoDiff.IParametricCompiledTerm compiledFunc = func.Compile(variables.ToArray(), parameters.ToArray());
+
+      List<SymbolicExpressionTreeTerminalNode> terminalNodes = null;
+      if (updateVariableWeights)
+        terminalNodes = tree.Root.IterateNodesPrefix().OfType<SymbolicExpressionTreeTerminalNode>().ToList();
+      else
+        terminalNodes = new List<SymbolicExpressionTreeTerminalNode>(tree.Root.IterateNodesPrefix().OfType<ConstantTreeNode>());
+
+      //extract inital constants
       double[] c = new double[variables.Count];
-
       {
         c[0] = 0.0;
         c[1] = 1.0;
-        //extract inital constants
         int i = 2;
         foreach (var node in terminalNodes) {
@@ -191,5 +206,5 @@
           if (constantTreeNode != null)
             c[i++] = constantTreeNode.Value;
-          else if (variableTreeNode != null)
+          else if (updateVariableWeights && variableTreeNode != null)
             c[i++] = variableTreeNode.Weight;
         }
@@ -234,10 +249,10 @@
 
       //info == -7  => constant optimization failed due to wrong gradient
-      if (info != -7) UpdateConstants(tree, c.Skip(2).ToArray());
+      if (info != -7) UpdateConstants(tree, c.Skip(2).ToArray(), updateVariableWeights);
       var quality = SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.Calculate(interpreter, tree, lowerEstimationLimit, upperEstimationLimit, problemData, rows, applyLinearScaling);
 
-      if (!updateConstantsInTree) UpdateConstants(tree, originalConstants.Skip(2).ToArray());
+      if (!updateConstantsInTree) UpdateConstants(tree, originalConstants.Skip(2).ToArray(), updateVariableWeights);
       if (originalQuality - quality > 0.001 || double.IsNaN(quality)) {
-        UpdateConstants(tree, originalConstants.Skip(2).ToArray());
+        UpdateConstants(tree, originalConstants.Skip(2).ToArray(), updateVariableWeights);
         return originalQuality;
       }
@@ -245,5 +260,5 @@
     }
 
-    private static void UpdateConstants(ISymbolicExpressionTree tree, double[] constants) {
+    private static void UpdateConstants(ISymbolicExpressionTree tree, double[] constants, bool updateVariableWeights) {
       int i = 0;
       foreach (var node in tree.Root.IterateNodesPrefix().OfType<SymbolicExpressionTreeTerminalNode>()) {
@@ -252,5 +267,5 @@
         if (constantTreeNode != null)
           constantTreeNode.Value = constants[i++];
-        else if (variableTreeNode != null)
+        else if (updateVariableWeights && variableTreeNode != null)
           variableTreeNode.Weight = constants[i++];
       }
@@ -271,5 +286,5 @@
     }
 
-    private static bool TryTransformToAutoDiff(ISymbolicExpressionTreeNode node, List<AutoDiff.Variable> variables, List<AutoDiff.Variable> parameters, List<string> variableNames, out AutoDiff.Term term) {
+    private static bool TryTransformToAutoDiff(ISymbolicExpressionTreeNode node, List<AutoDiff.Variable> variables, List<AutoDiff.Variable> parameters, List<string> variableNames, bool updateVariableWeights, out AutoDiff.Term term) {
       if (node.Symbol is Constant) {
         var var = new AutoDiff.Variable();
@@ -283,7 +298,12 @@
         parameters.Add(par);
         variableNames.Add(varNode.VariableName);
-        var w = new AutoDiff.Variable();
-        variables.Add(w);
-        term = AutoDiff.TermBuilder.Product(w, par);
+
+        if (updateVariableWeights) {
+          var w = new AutoDiff.Variable();
+          variables.Add(w);
+          term = AutoDiff.TermBuilder.Product(w, par);
+        } else {
+          term = par;
+        }
         return true;
       }
@@ -292,5 +312,5 @@
         foreach (var subTree in node.Subtrees) {
           AutoDiff.Term t;
-          if (!TryTransformToAutoDiff(subTree, variables, parameters, variableNames, out t)) {
+          if (!TryTransformToAutoDiff(subTree, variables, parameters, variableNames, updateVariableWeights, out t)) {
             term = null;
             return false;
@@ -305,5 +325,5 @@
         for (int i = 0; i < node.SubtreeCount; i++) {
           AutoDiff.Term t;
-          if (!TryTransformToAutoDiff(node.GetSubtree(i), variables, parameters, variableNames, out t)) {
+          if (!TryTransformToAutoDiff(node.GetSubtree(i), variables, parameters, variableNames, updateVariableWeights, out t)) {
             term = null;
             return false;
@@ -316,47 +336,35 @@
       }
       if (node.Symbol is Multiplication) {
-        AutoDiff.Term a, b;
-        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out a) ||
-          !TryTransformToAutoDiff(node.GetSubtree(1), variables, parameters, variableNames, out b)) {
-          term = null;
-          return false;
-        } else {
-          List<AutoDiff.Term> factors = new List<Term>();
-          foreach (var subTree in node.Subtrees.Skip(2)) {
-            AutoDiff.Term f;
-            if (!TryTransformToAutoDiff(subTree, variables, parameters, variableNames, out f)) {
-              term = null;
-              return false;
-            }
-            factors.Add(f);
+        List<AutoDiff.Term> terms = new List<Term>();
+        foreach (var subTree in node.Subtrees) {
+          AutoDiff.Term t;
+          if (!TryTransformToAutoDiff(subTree, variables, parameters, variableNames, updateVariableWeights, out t)) {
+            term = null;
+            return false;
           }
-          term = AutoDiff.TermBuilder.Product(a, b, factors.ToArray());
-          return true;
-        }
+          terms.Add(t);
+        }
+        if (terms.Count == 1) term = terms[0];
+        else term = terms.Aggregate((a, b) => new AutoDiff.Product(a, b));
+        return true;
+
       }
       if (node.Symbol is Division) {
-        // only works for at least two subtrees
-        AutoDiff.Term a, b;
-        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out a) ||
-          !TryTransformToAutoDiff(node.GetSubtree(1), variables, parameters, variableNames, out b)) {
-          term = null;
-          return false;
-        } else {
-          List<AutoDiff.Term> factors = new List<Term>();
-          foreach (var subTree in node.Subtrees.Skip(2)) {
-            AutoDiff.Term f;
-            if (!TryTransformToAutoDiff(subTree, variables, parameters, variableNames, out f)) {
-              term = null;
-              return false;
-            }
-            factors.Add(1.0 / f);
+        List<AutoDiff.Term> terms = new List<Term>();
+        foreach (var subTree in node.Subtrees) {
+          AutoDiff.Term t;
+          if (!TryTransformToAutoDiff(subTree, variables, parameters, variableNames, updateVariableWeights, out t)) {
+            term = null;
+            return false;
           }
-          term = AutoDiff.TermBuilder.Product(a, 1.0 / b, factors.ToArray());
-          return true;
-        }
+          terms.Add(t);
+        }
+        if (terms.Count == 1) term = 1.0 / terms[0];
+        else term = terms.Aggregate((a, b) => new AutoDiff.Product(a, 1.0 / b));
+        return true;
       }
       if (node.Symbol is Logarithm) {
         AutoDiff.Term t;
-        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t)) {
+        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, updateVariableWeights, out t)) {
           term = null;
           return false;
@@ -368,5 +376,5 @@
       if (node.Symbol is Exponential) {
         AutoDiff.Term t;
-        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t)) {
+        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, updateVariableWeights, out t)) {
           term = null;
           return false;
@@ -378,5 +386,5 @@
       if (node.Symbol is Square) {
         AutoDiff.Term t;
-        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t)) {
+        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, updateVariableWeights, out t)) {
           term = null;
           return false;
@@ -385,7 +393,8 @@
           return true;
         }
-      } if (node.Symbol is SquareRoot) {
-        AutoDiff.Term t;
-        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t)) {
+      }
+      if (node.Symbol is SquareRoot) {
+        AutoDiff.Term t;
+        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, updateVariableWeights, out t)) {
           term = null;
           return false;
@@ -394,7 +403,8 @@
           return true;
         }
-      } if (node.Symbol is Sine) {
-        AutoDiff.Term t;
-        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t)) {
+      }
+      if (node.Symbol is Sine) {
+        AutoDiff.Term t;
+        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, updateVariableWeights, out t)) {
           term = null;
           return false;
@@ -403,7 +413,8 @@
           return true;
         }
-      } if (node.Symbol is Cosine) {
-        AutoDiff.Term t;
-        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t)) {
+      }
+      if (node.Symbol is Cosine) {
+        AutoDiff.Term t;
+        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, updateVariableWeights, out t)) {
           term = null;
           return false;
@@ -412,7 +423,8 @@
           return true;
         }
-      } if (node.Symbol is Tangent) {
-        AutoDiff.Term t;
-        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t)) {
+      }
+      if (node.Symbol is Tangent) {
+        AutoDiff.Term t;
+        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, updateVariableWeights, out t)) {
           term = null;
           return false;
@@ -421,7 +433,8 @@
           return true;
         }
-      } if (node.Symbol is Erf) {
-        AutoDiff.Term t;
-        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t)) {
+      }
+      if (node.Symbol is Erf) {
+        AutoDiff.Term t;
+        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, updateVariableWeights, out t)) {
           term = null;
           return false;
@@ -430,7 +443,8 @@
           return true;
         }
-      } if (node.Symbol is Norm) {
-        AutoDiff.Term t;
-        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t)) {
+      }
+      if (node.Symbol is Norm) {
+        AutoDiff.Term t;
+        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, updateVariableWeights, out t)) {
           term = null;
           return false;
@@ -446,5 +460,5 @@
         variables.Add(alpha);
         AutoDiff.Term branchTerm;
-        if (TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out branchTerm)) {
+        if (TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, updateVariableWeights, out branchTerm)) {
           term = branchTerm * alpha + beta;
           return true;
Index: branches/crossvalidation-2434/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/SymbolicRegressionSingleObjectiveTrainingBestSolutionAnalyzer.cs
===================================================================
--- branches/crossvalidation-2434/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/SymbolicRegressionSingleObjectiveTrainingBestSolutionAnalyzer.cs	(revision 13401)
+++ branches/crossvalidation-2434/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/SymbolicRegressionSingleObjectiveTrainingBestSolutionAnalyzer.cs	(revision 14029)
@@ -63,5 +63,5 @@
 
     protected override ISymbolicRegressionSolution CreateSolution(ISymbolicExpressionTree bestTree, double bestQuality) {
-      var model = new SymbolicRegressionModel((ISymbolicExpressionTree)bestTree.Clone(), SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper);
+      var model = new SymbolicRegressionModel(ProblemDataParameter.ActualValue.TargetVariable, (ISymbolicExpressionTree)bestTree.Clone(), SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper);
       if (ApplyLinearScalingParameter.ActualValue.Value) model.Scale(ProblemDataParameter.ActualValue);
       return new SymbolicRegressionSolution(model, (IRegressionProblemData)ProblemDataParameter.ActualValue.Clone());
Index: branches/crossvalidation-2434/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/SymbolicRegressionSingleObjectiveTrainingParetoBestSolutionAnalyzer.cs
===================================================================
--- branches/crossvalidation-2434/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/SymbolicRegressionSingleObjectiveTrainingParetoBestSolutionAnalyzer.cs	(revision 13401)
+++ branches/crossvalidation-2434/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/SymbolicRegressionSingleObjectiveTrainingParetoBestSolutionAnalyzer.cs	(revision 14029)
@@ -42,5 +42,5 @@
 
     protected override ISymbolicRegressionSolution CreateSolution(ISymbolicExpressionTree bestTree) {
-      var model = new SymbolicRegressionModel((ISymbolicExpressionTree)bestTree.Clone(), SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper);
+      var model = new SymbolicRegressionModel(ProblemDataParameter.ActualValue.TargetVariable, (ISymbolicExpressionTree)bestTree.Clone(), SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper);
       if (ApplyLinearScalingParameter.ActualValue.Value) model.Scale(ProblemDataParameter.ActualValue);
       return new SymbolicRegressionSolution(model, (IRegressionProblemData)ProblemDataParameter.ActualValue.Clone());
Index: branches/crossvalidation-2434/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/SymbolicRegressionSingleObjectiveValidationBestSolutionAnalyzer.cs
===================================================================
--- branches/crossvalidation-2434/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/SymbolicRegressionSingleObjectiveValidationBestSolutionAnalyzer.cs	(revision 13401)
+++ branches/crossvalidation-2434/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/SymbolicRegressionSingleObjectiveValidationBestSolutionAnalyzer.cs	(revision 14029)
@@ -55,5 +55,5 @@
 
     protected override ISymbolicRegressionSolution CreateSolution(ISymbolicExpressionTree bestTree, double bestQuality) {
-      var model = new SymbolicRegressionModel((ISymbolicExpressionTree)bestTree.Clone(), SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper);
+      var model = new SymbolicRegressionModel(ProblemDataParameter.ActualValue.TargetVariable, (ISymbolicExpressionTree)bestTree.Clone(), SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper);
       if (ApplyLinearScalingParameter.ActualValue.Value) model.Scale(ProblemDataParameter.ActualValue);
       return new SymbolicRegressionSolution(model, (IRegressionProblemData)ProblemDataParameter.ActualValue.Clone());
Index: branches/crossvalidation-2434/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/SymbolicRegressionSingleObjectiveValidationParetoBestSolutionAnalyzer.cs
===================================================================
--- branches/crossvalidation-2434/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/SymbolicRegressionSingleObjectiveValidationParetoBestSolutionAnalyzer.cs	(revision 13401)
+++ branches/crossvalidation-2434/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/SymbolicRegressionSingleObjectiveValidationParetoBestSolutionAnalyzer.cs	(revision 14029)
@@ -42,5 +42,5 @@
 
     protected override ISymbolicRegressionSolution CreateSolution(ISymbolicExpressionTree bestTree) {
-      var model = new SymbolicRegressionModel((ISymbolicExpressionTree)bestTree.Clone(), SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper);
+      var model = new SymbolicRegressionModel(ProblemDataParameter.ActualValue.TargetVariable, (ISymbolicExpressionTree)bestTree.Clone(), SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper);
       if (ApplyLinearScalingParameter.ActualValue.Value) model.Scale(ProblemDataParameter.ActualValue);
       return new SymbolicRegressionSolution(model, (IRegressionProblemData)ProblemDataParameter.ActualValue.Clone());
Index: branches/crossvalidation-2434/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/SymbolicRegressionSolutionsAnalyzer.cs
===================================================================
--- branches/crossvalidation-2434/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/SymbolicRegressionSolutionsAnalyzer.cs	(revision 13401)
+++ branches/crossvalidation-2434/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/SymbolicRegressionSolutionsAnalyzer.cs	(revision 14029)
@@ -27,4 +27,5 @@
 using HeuristicLab.Common;
 using HeuristicLab.Core;
+using HeuristicLab.Data;
 using HeuristicLab.Operators;
 using HeuristicLab.Optimization;
@@ -33,10 +34,19 @@
 
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Regression {
+  [StorableClass]
   public class SymbolicRegressionSolutionsAnalyzer : SingleSuccessorOperator, IAnalyzer {
     private const string ResultCollectionParameterName = "Results";
     private const string RegressionSolutionQualitiesResultName = "Regression Solution Qualities";
+    private const string TrainingQualityParameterName = "TrainingRSquared";
+    private const string TestQualityParameterName = "TestRSquared";
 
     public ILookupParameter<ResultCollection> ResultCollectionParameter {
       get { return (ILookupParameter<ResultCollection>)Parameters[ResultCollectionParameterName]; }
+    }
+    public ILookupParameter<DoubleValue> TrainingQualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters[TrainingQualityParameterName]; }
+    }
+    public ILookupParameter<DoubleValue> TestQualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters[TestQualityParameterName]; }
     }
 
@@ -55,4 +65,18 @@
     public SymbolicRegressionSolutionsAnalyzer() {
       Parameters.Add(new LookupParameter<ResultCollection>(ResultCollectionParameterName, "The result collection to store the analysis results."));
+      Parameters.Add(new LookupParameter<DoubleValue>(TrainingQualityParameterName));
+      Parameters.Add(new LookupParameter<DoubleValue>(TestQualityParameterName));
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      // BackwardsCompatibility3.3
+
+      #region Backwards compatible code, remove with 3.4
+      if (!Parameters.ContainsKey(TrainingQualityParameterName))
+        Parameters.Add(new LookupParameter<DoubleValue>(TrainingQualityParameterName));
+      if (!Parameters.ContainsKey(TestQualityParameterName))
+        Parameters.Add(new LookupParameter<DoubleValue>(TestQualityParameterName));
+      #endregion
     }
 
@@ -66,18 +90,37 @@
 
       var dataTable = (DataTable)results[RegressionSolutionQualitiesResultName].Value;
+
+      // only if the parameters are available (not available in old persisted code)
+      ILookupParameter<DoubleValue> trainingQualityParam = null;
+      ILookupParameter<DoubleValue> testQualityParam = null;
+      // store actual names of parameter because it is changed below
+      trainingQualityParam = TrainingQualityParameter;
+      string prevTrainingQualityParamName = trainingQualityParam.ActualName;
+      testQualityParam = TestQualityParameter;
+      string prevTestQualityParamName = testQualityParam.ActualName;
       foreach (var result in results.Where(r => r.Value is IRegressionSolution)) {
         var solution = (IRegressionSolution)result.Value;
 
-        var trainingR2 = result.Name + Environment.NewLine + "Training R²";
-        if (!dataTable.Rows.ContainsKey(trainingR2))
-          dataTable.Rows.Add(new DataRow(trainingR2));
+        var trainingR2Name = result.Name + " Training R²";
+        if (!dataTable.Rows.ContainsKey(trainingR2Name))
+          dataTable.Rows.Add(new DataRow(trainingR2Name));
 
-        var testR2 = result.Name + Environment.NewLine + " Test R²";
-        if (!dataTable.Rows.ContainsKey(testR2))
-          dataTable.Rows.Add(new DataRow(testR2));
+        var testR2Name = result.Name + " Test R²";
+        if (!dataTable.Rows.ContainsKey(testR2Name))
+          dataTable.Rows.Add(new DataRow(testR2Name));
 
-        dataTable.Rows[trainingR2].Values.Add(solution.TrainingRSquared);
-        dataTable.Rows[testR2].Values.Add(solution.TestRSquared);
+        dataTable.Rows[trainingR2Name].Values.Add(solution.TrainingRSquared);
+        dataTable.Rows[testR2Name].Values.Add(solution.TestRSquared);
+
+        // also add training and test R² to the scope using the parameters
+        // HACK: we change the ActualName of the parameter to write two variables for each solution in the results collection
+        trainingQualityParam.ActualName = trainingR2Name;
+        trainingQualityParam.ActualValue = new DoubleValue(solution.TrainingRSquared);
+        testQualityParam.ActualName = testR2Name;
+        testQualityParam.ActualValue = new DoubleValue(solution.TestRSquared);
       }
+
+      trainingQualityParam.ActualName = prevTrainingQualityParamName;
+      testQualityParam.ActualName = prevTestQualityParamName;
 
       return base.Apply();
Index: branches/crossvalidation-2434/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SymbolicRegressionModel.cs
===================================================================
--- branches/crossvalidation-2434/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SymbolicRegressionModel.cs	(revision 13401)
+++ branches/crossvalidation-2434/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SymbolicRegressionModel.cs	(revision 14029)
@@ -20,4 +20,5 @@
 #endregion
 
+using System;
 using System.Collections.Generic;
 using HeuristicLab.Common;
@@ -33,13 +34,24 @@
   [Item(Name = "Symbolic Regression Model", Description = "Represents a symbolic regression model.")]
   public class SymbolicRegressionModel : SymbolicDataAnalysisModel, ISymbolicRegressionModel {
-
+    [Storable]
+    private readonly string targetVariable;
+    public string TargetVariable {
+      get { return targetVariable; }
+    }
 
     [StorableConstructor]
     protected SymbolicRegressionModel(bool deserializing) : base(deserializing) { }
-    protected SymbolicRegressionModel(SymbolicRegressionModel original, Cloner cloner) : base(original, cloner) { }
 
-    public SymbolicRegressionModel(ISymbolicExpressionTree tree, ISymbolicDataAnalysisExpressionTreeInterpreter interpreter,
+    protected SymbolicRegressionModel(SymbolicRegressionModel original, Cloner cloner)
+      : base(original, cloner) {
+      this.targetVariable = original.targetVariable;
+    }
+
+    public SymbolicRegressionModel(string targetVariable, ISymbolicExpressionTree tree,
+      ISymbolicDataAnalysisExpressionTreeInterpreter interpreter,
       double lowerEstimationLimit = double.MinValue, double upperEstimationLimit = double.MaxValue)
-      : base(tree, interpreter, lowerEstimationLimit, upperEstimationLimit) { }
+      : base(tree, interpreter, lowerEstimationLimit, upperEstimationLimit) {
+      this.targetVariable = targetVariable;
+    }
 
     public override IDeepCloneable Clone(Cloner cloner) {
Index: branches/crossvalidation-2434/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SymbolicRegressionPruningOperator.cs
===================================================================
--- branches/crossvalidation-2434/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SymbolicRegressionPruningOperator.cs	(revision 13401)
+++ branches/crossvalidation-2434/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SymbolicRegressionPruningOperator.cs	(revision 14029)
@@ -69,5 +69,6 @@
 
     protected override ISymbolicDataAnalysisModel CreateModel(ISymbolicExpressionTree tree, ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, IDataAnalysisProblemData problemData, DoubleLimit estimationLimits) {
-      return new SymbolicRegressionModel(tree, interpreter, estimationLimits.Lower, estimationLimits.Upper);
+      var regressionProblemData = (IRegressionProblemData)problemData;
+      return new SymbolicRegressionModel(regressionProblemData.TargetVariable, tree, interpreter, estimationLimits.Lower, estimationLimits.Upper);
     }
 
@@ -83,5 +84,5 @@
     public static ISymbolicExpressionTree Prune(ISymbolicExpressionTree tree, SymbolicRegressionSolutionImpactValuesCalculator impactValuesCalculator, ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, IRegressionProblemData problemData, DoubleLimit estimationLimits, IEnumerable<int> rows, double nodeImpactThreshold = 0.0, bool pruneOnlyZeroImpactNodes = false) {
       var clonedTree = (ISymbolicExpressionTree)tree.Clone();
-      var model = new SymbolicRegressionModel(clonedTree, interpreter, estimationLimits.Lower, estimationLimits.Upper);
+      var model = new SymbolicRegressionModel(problemData.TargetVariable, clonedTree, interpreter, estimationLimits.Lower, estimationLimits.Upper);
       var nodes = clonedTree.Root.GetSubtree(0).GetSubtree(0).IterateNodesPrefix().ToList(); // skip the nodes corresponding to the ProgramRootSymbol and the StartSymbol
 
Index: branches/crossvalidation-2434/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SymbolicRegressionSolution.cs
===================================================================
--- branches/crossvalidation-2434/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SymbolicRegressionSolution.cs	(revision 13401)
+++ branches/crossvalidation-2434/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SymbolicRegressionSolution.cs	(revision 14029)
@@ -118,5 +118,4 @@
       estimationLimitResults.Add(new Result(TestNaNEvaluationsResultName, "", new IntValue()));
       Add(new Result(EstimationLimitsResultsResultName, "Results concerning the estimation limits of symbolic regression solution", estimationLimitResults));
-
       RecalculateResults();
     }
