Index: branches/2974_Constants_Optimization/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression-3.4.csproj
===================================================================
--- branches/2974_Constants_Optimization/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression-3.4.csproj	(revision 16464)
+++ branches/2974_Constants_Optimization/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression-3.4.csproj	(revision 16500)
@@ -192,5 +192,4 @@
     <Compile Include="Plugin.cs" />
     <Compile Include="SingleObjective\ConstantOptimizationAnalyzer.cs" />
-    <Compile Include="SingleObjective\Evaluators\ConstantsOptimizationEvaluator.cs" />
     <Compile Include="SingleObjective\Evaluators\SymbolicRegressionMeanRelativeErrorEvaluator.cs" />
     <Compile Include="SingleObjective\SymbolicRegressionSolutionsAnalyzer.cs" />
Index: branches/2974_Constants_Optimization/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/ConstantsOptimizationEvaluator.cs
===================================================================
--- branches/2974_Constants_Optimization/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/ConstantsOptimizationEvaluator.cs	(revision 16464)
+++ 	(revision )
@@ -1,311 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2018 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.Optimization;
-using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-using static HeuristicLab.Problems.DataAnalysis.Symbolic.TreeToAutoDiffTermConverter;
-
-namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Regression {
-  [Item("New Constant Optimization Evaluator", "Calculates Pearson MSE of a symbolic regression solution and optimizes the constant used.")]
-  [StorableClass]
-  public class ConstantsOptimizationEvaluator : SymbolicRegressionSingleObjectiveEvaluator {
-    private const string ConstantOptimizationIterationsParameterName = "ConstantOptimizationIterations";
-    private const string ConstantOptimizationImprovementParameterName = "ConstantOptimizationImprovement";
-    private const string ConstantOptimizationProbabilityParameterName = "ConstantOptimizationProbability";
-    private const string ConstantOptimizationRowsPercentageParameterName = "ConstantOptimizationRowsPercentage";
-    private const string UpdateConstantsInTreeParameterName = "UpdateConstantsInSymbolicExpressionTree";
-    private const string UpdateVariableWeightsParameterName = "Update Variable Weights";
-
-    private const string FunctionEvaluationsResultParameterName = "Constants Optimization Function Evaluations";
-    private const string GradientEvaluationsResultParameterName = "Constants Optimization Gradient Evaluations";
-    private const string CountEvaluationsParameterName = "Count Function and Gradient Evaluations";
-
-    public IFixedValueParameter<IntValue> ConstantOptimizationIterationsParameter {
-      get { return (IFixedValueParameter<IntValue>)Parameters[ConstantOptimizationIterationsParameterName]; }
-    }
-    public IFixedValueParameter<DoubleValue> ConstantOptimizationImprovementParameter {
-      get { return (IFixedValueParameter<DoubleValue>)Parameters[ConstantOptimizationImprovementParameterName]; }
-    }
-    public IFixedValueParameter<PercentValue> ConstantOptimizationProbabilityParameter {
-      get { return (IFixedValueParameter<PercentValue>)Parameters[ConstantOptimizationProbabilityParameterName]; }
-    }
-    public IFixedValueParameter<PercentValue> ConstantOptimizationRowsPercentageParameter {
-      get { return (IFixedValueParameter<PercentValue>)Parameters[ConstantOptimizationRowsPercentageParameterName]; }
-    }
-    public IFixedValueParameter<BoolValue> UpdateConstantsInTreeParameter {
-      get { return (IFixedValueParameter<BoolValue>)Parameters[UpdateConstantsInTreeParameterName]; }
-    }
-    public IFixedValueParameter<BoolValue> UpdateVariableWeightsParameter {
-      get { return (IFixedValueParameter<BoolValue>)Parameters[UpdateVariableWeightsParameterName]; }
-    }
-
-    public IResultParameter<IntValue> FunctionEvaluationsResultParameter {
-      get { return (IResultParameter<IntValue>)Parameters[FunctionEvaluationsResultParameterName]; }
-    }
-    public IResultParameter<IntValue> GradientEvaluationsResultParameter {
-      get { return (IResultParameter<IntValue>)Parameters[GradientEvaluationsResultParameterName]; }
-    }
-    public IFixedValueParameter<BoolValue> CountEvaluationsParameter {
-      get { return (IFixedValueParameter<BoolValue>)Parameters[CountEvaluationsParameterName]; }
-    }
-
-
-    public IntValue ConstantOptimizationIterations {
-      get { return ConstantOptimizationIterationsParameter.Value; }
-    }
-    public DoubleValue ConstantOptimizationImprovement {
-      get { return ConstantOptimizationImprovementParameter.Value; }
-    }
-    public PercentValue ConstantOptimizationProbability {
-      get { return ConstantOptimizationProbabilityParameter.Value; }
-    }
-    public PercentValue ConstantOptimizationRowsPercentage {
-      get { return ConstantOptimizationRowsPercentageParameter.Value; }
-    }
-    public bool UpdateConstantsInTree {
-      get { return UpdateConstantsInTreeParameter.Value.Value; }
-      set { UpdateConstantsInTreeParameter.Value.Value = value; }
-    }
-
-    public bool UpdateVariableWeights {
-      get { return UpdateVariableWeightsParameter.Value.Value; }
-      set { UpdateVariableWeightsParameter.Value.Value = value; }
-    }
-
-    public bool CountEvaluations {
-      get { return CountEvaluationsParameter.Value.Value; }
-      set { CountEvaluationsParameter.Value.Value = value; }
-    }
-
-    public override bool Maximization {
-      get { return true; }
-    }
-
-    [StorableConstructor]
-    protected ConstantsOptimizationEvaluator(bool deserializing) : base(deserializing) { }
-    protected ConstantsOptimizationEvaluator(ConstantsOptimizationEvaluator original, Cloner cloner)
-      : base(original, cloner) {
-    }
-    public ConstantsOptimizationEvaluator()
-      : 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) { 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)) { Hidden = true });
-      Parameters.Add(new FixedValueParameter<BoolValue>(UpdateVariableWeightsParameterName, "Determines if the variable weights in the tree should be  optimized.", new BoolValue(true)) { Hidden = true });
-
-      Parameters.Add(new FixedValueParameter<BoolValue>(CountEvaluationsParameterName, "Determines if function and gradient evaluation should be counted.", new BoolValue(false)));
-      Parameters.Add(new ResultParameter<IntValue>(FunctionEvaluationsResultParameterName, "The number of function evaluations performed by the constants optimization evaluator", "Results", new IntValue()));
-      Parameters.Add(new ResultParameter<IntValue>(GradientEvaluationsResultParameterName, "The number of gradient evaluations performed by the constants optimization evaluator", "Results", new IntValue()));
-    }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new ConstantsOptimizationEvaluator(this, cloner);
-    }
-
-    private static readonly object locker = new object();
-    public override IOperation InstrumentedApply() {
-      var solution = SymbolicExpressionTreeParameter.ActualValue;
-      double quality;
-      if (RandomParameter.ActualValue.NextDouble() < ConstantOptimizationProbability.Value) {
-        IEnumerable<int> constantOptimizationRows = GenerateRowsToEvaluate(ConstantOptimizationRowsPercentage.Value);
-        var counter = new EvaluationsCounter();
-        quality = OptimizeConstants(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, solution, ProblemDataParameter.ActualValue,
-           constantOptimizationRows, ApplyLinearScalingParameter.ActualValue.Value, ConstantOptimizationIterations.Value, updateVariableWeights: UpdateVariableWeights, lowerEstimationLimit: EstimationLimitsParameter.ActualValue.Lower, upperEstimationLimit: EstimationLimitsParameter.ActualValue.Upper, updateConstantsInTree: UpdateConstantsInTree, counter: counter);
-
-        if (ConstantOptimizationRowsPercentage.Value != RelativeNumberOfEvaluatedSamplesParameter.ActualValue.Value) {
-          var evaluationRows = GenerateRowsToEvaluate();
-          quality = SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, solution, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, ProblemDataParameter.ActualValue, evaluationRows, ApplyLinearScalingParameter.ActualValue.Value);
-        }
-
-        if (CountEvaluations) {
-          lock (locker) {
-            FunctionEvaluationsResultParameter.ActualValue.Value += counter.FunctionEvaluations;
-            GradientEvaluationsResultParameter.ActualValue.Value += counter.GradientEvaluations;
-          }
-        }
-
-      } else {
-        var evaluationRows = GenerateRowsToEvaluate();
-        quality = SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, solution, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, ProblemDataParameter.ActualValue, evaluationRows, ApplyLinearScalingParameter.ActualValue.Value);
-      }
-      QualityParameter.ActualValue = new DoubleValue(quality);
-
-      return base.InstrumentedApply();
-    }
-
-    public override double Evaluate(IExecutionContext context, ISymbolicExpressionTree tree, IRegressionProblemData problemData, IEnumerable<int> rows) {
-      SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = context;
-      EstimationLimitsParameter.ExecutionContext = context;
-      ApplyLinearScalingParameter.ExecutionContext = context;
-      FunctionEvaluationsResultParameter.ExecutionContext = context;
-      GradientEvaluationsResultParameter.ExecutionContext = context;
-
-      // Pearson R² evaluator is used on purpose instead of the const-opt evaluator, 
-      // because Evaluate() is used to get the quality of evolved models on 
-      // different partitions of the dataset (e.g., best validation model)
-      double r2 = SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, problemData, rows, ApplyLinearScalingParameter.ActualValue.Value);
-
-      SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = null;
-      EstimationLimitsParameter.ExecutionContext = null;
-      ApplyLinearScalingParameter.ExecutionContext = null;
-      FunctionEvaluationsResultParameter.ExecutionContext = null;
-      GradientEvaluationsResultParameter.ExecutionContext = null;
-
-      return r2;
-    }
-
-    public class EvaluationsCounter {
-      public int FunctionEvaluations = 0;
-      public int GradientEvaluations = 0;
-    }
-
-    [ThreadStatic]
-    private static double[,] x = null;
-    [ThreadStatic]
-    private static IDataset ds = null;
-    [ThreadStatic]
-    private static Dictionary<DataForVariable, AutoDiff.Variable> parameters;
-
-    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, Action<double[], double, object> iterationCallback = null, EvaluationsCounter counter = null) {
-
-      if (ds == null || ds != problemData.Dataset) {
-        ds = problemData.Dataset;
-        parameters = ConstantsOptimization.Util.ExtractParameters(problemData.Dataset);
-        x = ConstantsOptimization.Util.ExtractData(ds, parameters.Keys, rows);
-        
-      }
-      double[] y = ds.GetDoubleValues(problemData.TargetVariable, rows).ToArray();
-
-
-      // numeric constants in the tree become variables for constant opt
-      // variables in the tree become parameters (fixed values) for constant opt
-      // for each parameter (variable in the original tree) we store the 
-      // variable name, variable value (for factor vars) and lag as a DataForVariable object.
-      // A dictionary is used to find parameters
-      TreeToAutoDiffTermConverter.ParametricFunction func;
-      TreeToAutoDiffTermConverter.ParametricFunctionGradient func_grad;
-      double[] initialConstants;
-
-      if (!TreeToAutoDiffTermConverter.TryConvertToAutoDiff(tree, updateVariableWeights, applyLinearScaling, parameters, out func, out func_grad, out initialConstants))
-        throw new NotSupportedException("Could not optimize constants of symbolic expression tree due to not supported symbols used in the tree.");
-      if (parameters.Count == 0) return 0.0; // gkronber: constant expressions always have a R² of 0.0 
-
-      //extract inital constants
-      double[] c;
-      if (applyLinearScaling) {
-        c = new double[initialConstants.Length + 2];
-        c[0] = 0.0;
-        c[1] = 1.0;
-        Array.Copy(initialConstants, 0, c, 2, initialConstants.Length);
-      } else {
-        c = (double[])initialConstants.Clone();
-      }
-
-      double originalQuality = SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.Calculate(interpreter, tree, lowerEstimationLimit, upperEstimationLimit, problemData, rows, applyLinearScaling);
-
-      if (counter == null) counter = new EvaluationsCounter();
-      var rowEvaluationsCounter = new EvaluationsCounter();
-
-      alglib.lsfitstate state;
-      alglib.lsfitreport rep;
-      int retVal;
-
-
-      int n = x.GetLength(0);
-      int m = x.GetLength(1);
-      int k = c.Length;
-
-      alglib.ndimensional_pfunc function_cx_1_func = CreatePFunc(func);
-      alglib.ndimensional_pgrad function_cx_1_grad = CreatePGrad(func_grad);
-      alglib.ndimensional_rep xrep = (p, f, obj) => iterationCallback(p, f, obj);
-
-      try {
-        alglib.lsfitcreatefg(x, y, c, n, m, k, false, out state);
-        alglib.lsfitsetcond(state, 0.0, 0.0, maxIterations);
-        alglib.lsfitsetxrep(state, iterationCallback != null);
-        //alglib.lsfitsetgradientcheck(state, 0.001);
-        alglib.lsfitfit(state, function_cx_1_func, function_cx_1_grad, xrep, rowEvaluationsCounter);
-        alglib.lsfitresults(state, out retVal, out c, out rep);
-      } catch (ArithmeticException) {
-        return originalQuality;
-      } catch (alglib.alglibexception) {
-        return originalQuality;
-      }
-
-      counter.FunctionEvaluations += rowEvaluationsCounter.FunctionEvaluations / n;
-      counter.GradientEvaluations += rowEvaluationsCounter.GradientEvaluations / n;
-
-      //retVal == -7  => constant optimization failed due to wrong gradient
-      if (retVal != -7) {
-        if (applyLinearScaling) {
-          var tmp = new double[c.Length - 2];
-          Array.Copy(c, 2, tmp, 0, tmp.Length);
-          ConstantsOptimization.Util.UpdateConstants(tree, tmp);
-        } else ConstantsOptimization.Util.UpdateConstants(tree, c);
-      }
-      var quality = SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.Calculate(interpreter, tree, lowerEstimationLimit, upperEstimationLimit, problemData, rows, applyLinearScaling);
-
-      if (!updateConstantsInTree)
-        ConstantsOptimization.Util.UpdateConstants(tree, initialConstants);
-
-      if (originalQuality - quality > 0.001 || double.IsNaN(quality)) {
-        ConstantsOptimization.Util.UpdateConstants(tree, initialConstants);
-        return originalQuality;
-      }
-      return quality;
-    }
-
-    private static alglib.ndimensional_pfunc CreatePFunc(TreeToAutoDiffTermConverter.ParametricFunction func) {
-      return (double[] c, double[] x, ref double fx, object o) => {
-        fx = func(c, x);
-        var counter = (EvaluationsCounter)o;
-        counter.FunctionEvaluations++;
-      };
-    }
-
-    private static alglib.ndimensional_pgrad CreatePGrad(TreeToAutoDiffTermConverter.ParametricFunctionGradient func_grad) {
-      return (double[] c, double[] x, ref double fx, double[] grad, object o) => {
-        var tuple = func_grad(c, x);
-        fx = tuple.Item2;
-        Array.Copy(tuple.Item1, grad, grad.Length);
-        var counter = (EvaluationsCounter)o;
-        counter.GradientEvaluations++;
-      };
-    }
-    public static bool CanOptimizeConstants(ISymbolicExpressionTree tree) {
-      return TreeToAutoDiffTermConverter.IsCompatible(tree);
-    }
-  }
-}
Index: branches/2974_Constants_Optimization/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Constants Optimization/IConstantsOptimizer.cs
===================================================================
--- branches/2974_Constants_Optimization/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Constants Optimization/IConstantsOptimizer.cs	(revision 16500)
+++ branches/2974_Constants_Optimization/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Constants Optimization/IConstantsOptimizer.cs	(revision 16500)
@@ -0,0 +1,33 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
+  public interface IConstantsOptimizer {
+    bool ApplyLinearScaling { get; set; }
+    int MaximumIterations { get; set; }
+    //bool CountEvaluations { get; set; }
+    void OptimizeConstants(ISymbolicExpressionTree tree, IRegressionProblemData problemData, IEnumerable<int> rows);
+    void OptimizeConstants(ISymbolicExpressionTree tree, IDataset dataset, string targetVariable, IEnumerable<int> rows);
+  }
+}
Index: branches/2974_Constants_Optimization/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Constants Optimization/LMConstantsOptimizer.cs
===================================================================
--- branches/2974_Constants_Optimization/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Constants Optimization/LMConstantsOptimizer.cs	(revision 16500)
+++ branches/2974_Constants_Optimization/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Constants Optimization/LMConstantsOptimizer.cs	(revision 16500)
@@ -0,0 +1,108 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Encodings.SymbolicExpressionTreeEncoding;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
+  public class LMConstantsOptimizer {
+    private bool ApplyLinearScaling { get; set; }
+    private int MaximumIterations { get; set; }
+
+    public LMConstantsOptimizer() {
+
+    }
+    /// <summary>
+    /// 
+    /// </summary>
+    /// <param name="tree">The tree for which the constants are optimized.</param>
+    /// <param name="nodes">The nodes which should be adapted. The nodes must be the same (reference) as the ones used in the tree and the double values specify the inita</param>
+    /// <param name="x">The input data.</param>
+    /// <param name="y">The targer date.</param>
+    /// <param name="applyLinearScaling">Flag that determines whether linear scaling nodes should be added during the optimization.</param>
+    /// <returns> Fit of the symbolic expression tree in terms of ... </returns>
+    public static double OptimizeConstants(ISymbolicExpressionTree tree,IRegressionProblemData problemData, IEnumerable<int> rows, bool applyLinearScaling, int maxIterations = 10) {
+      //if (tree == null) throw new ArgumentNullException("tree");
+      //if (nodes == null) throw new ArgumentNullException("nodes");
+      //if (initialConstants == null) throw new ArgumentNullException("intitialConstants");
+      //if (problemData == null) throw new ArgumentNullException("problemData");
+
+      //if (!nodes.Any()) return 0;
+
+      var ds = problemData.Dataset;
+      var variables = ConstantsOptimization.Util.GenerateVariables(ds);
+      var laggedVariables = ConstantsOptimization.Util.ExtractLaggedVariables(tree);
+      var allVariables = variables.Union(laggedVariables);
+
+      double[,] x = ConstantsOptimization.Util.ExtractData(ds, allVariables, rows);
+      double[] y = ds.GetDoubleValues(problemData.TargetVariable, rows).ToArray();
+
+      double[] initialConstants;
+
+      AutoDiff.IParametricCompiledTerm term;
+      if (!TreeToAutoDiffTermConverter.TryConvertToAutoDiff(tree, applyLinearScaling, allVariables, out term, out initialConstants))
+        throw new NotSupportedException("Could not optimize constants of symbolic expression tree due to not supported symbols used in the tree.");
+
+      var constants = (double[])initialConstants.Clone();
+      alglib.lsfitstate state;
+      alglib.lsfitreport rep;
+      int retVal;
+
+      int numberOfRows = x.GetLength(0);
+      int numberOfColumns = x.GetLength(1);
+      int numberOfConstants = constants.Length;
+
+      try {
+        alglib.lsfitcreatefg(x, y, constants, numberOfRows, numberOfColumns, numberOfConstants, cheapfg: false, state: out state);
+        alglib.lsfitsetcond(state, 0.0, 0.0, maxIterations);
+        //alglib.lsfitsetgradientcheck(state, 0.001);
+        alglib.lsfitfit(state, Evaluate, EvaluateGradient, null, term);
+        alglib.lsfitresults(state, out retVal, out constants, out rep);
+      } catch (ArithmeticException) {
+        return double.NaN;
+      } catch (alglib.alglibexception) {
+        return double.NaN;
+      }
+
+      ConstantsOptimization.Util.UpdateConstants(tree, constants);
+
+      return rep.r2;
+    }
+
+    private static void Evaluate(double[] c, double[] x, ref double fx, object o) {
+      AutoDiff.IParametricCompiledTerm term = (AutoDiff.IParametricCompiledTerm)o;
+      fx = term.Evaluate(c, x);
+    }
+
+    private static void EvaluateGradient(double[] c, double[] x, ref double fx, double[] grad, object o) {
+      AutoDiff.IParametricCompiledTerm term = (AutoDiff.IParametricCompiledTerm)o;
+      Tuple<double[], double> result = term.Differentiate(c, x);
+      fx = result.Item2;
+      Array.Copy(result.Item1, grad, grad.Length);
+    }
+
+    public static bool CanOptimizeConstants(ISymbolicExpressionTree tree) {
+      return TreeToAutoDiffTermConverter.IsCompatible(tree);
+    }
+  }
+}
Index: branches/2974_Constants_Optimization/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Constants Optimization/Util.cs
===================================================================
--- branches/2974_Constants_Optimization/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Constants Optimization/Util.cs	(revision 16464)
+++ branches/2974_Constants_Optimization/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Constants Optimization/Util.cs	(revision 16500)
@@ -23,4 +23,5 @@
 using System.Collections.Generic;
 using System.Linq;
+using HeuristicLab.Common;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
 using static HeuristicLab.Problems.DataAnalysis.Symbolic.TreeToAutoDiffTermConverter;
@@ -48,10 +49,9 @@
     }
 
-    public static Dictionary<DataForVariable, AutoDiff.Variable> ExtractParameters(IDataset dataset) {
-      var parameters = new Dictionary<DataForVariable, AutoDiff.Variable>();
+    public static List<DataForVariable> GenerateVariables(IDataset dataset) {
+      var variables = new List<DataForVariable>();
       foreach (var doubleVariable in dataset.DoubleVariables) {
         var data = new DataForVariable(doubleVariable, string.Empty, 0);
-        var param = new AutoDiff.Variable();
-        parameters.Add(data, param);
+        variables.Add(data);
       }
 
@@ -59,9 +59,20 @@
         foreach (var stringValue in dataset.GetStringValues(stringVariable).Distinct()) {
           var data = new DataForVariable(stringVariable, stringValue, 0);
-          var param = new AutoDiff.Variable();
-          parameters.Add(data, param);
+          variables.Add(data);
         }
       }
-      return parameters;
+      return variables;
+    }
+
+    public static List<DataForVariable> ExtractLaggedVariables(ISymbolicExpressionTree tree) {
+      var variables = new HashSet<DataForVariable>();
+      foreach (var laggedNode in tree.IterateNodesPrefix().OfType<ILaggedTreeNode>()) {
+        var laggedVariableTreeNode = laggedNode as LaggedVariableTreeNode;
+        if (laggedVariableTreeNode != null) {
+          var data = new DataForVariable(laggedVariableTreeNode.VariableName, string.Empty, laggedVariableTreeNode.Lag);
+          if (!variables.Contains(data)) variables.Add(data);
+        }
+      }
+      return variables.ToList();
     }
 
@@ -79,5 +90,5 @@
           for (int j = 0; j < factorVarTreeNode.Weights.Length; j++)
             constants.Add(factorVarTreeNode.Weights[j]);
-        }        
+        } else throw new NotSupportedException(string.Format("Terminal nodes of type {0} are not supported.", node.GetType().GetPrettyName()));
       }
       return constants.ToArray();
@@ -97,5 +108,5 @@
           for (int j = 0; j < factorVarTreeNode.Weights.Length; j++)
             factorVarTreeNode.Weights[j] = constants[i++];
-        }
+        } else throw new NotSupportedException(string.Format("Terminal nodes of type {0} are not supported.", node.GetType().GetPrettyName()));
       }
     }
Index: branches/2974_Constants_Optimization/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/TreeToAutoDiffTermConverter.cs
===================================================================
--- branches/2974_Constants_Optimization/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/TreeToAutoDiffTermConverter.cs	(revision 16464)
+++ branches/2974_Constants_Optimization/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/TreeToAutoDiffTermConverter.cs	(revision 16500)
@@ -131,36 +131,43 @@
     }
 
-    public static bool TryConvertToAutoDiff(ISymbolicExpressionTree tree, bool makeVariableWeightsVariable, bool addLinearScalingTerms, Dictionary<DataForVariable, AutoDiff.Variable> parameters,
-      out ParametricFunction func,
-      out ParametricFunctionGradient func_grad,
-      out double[] initialConstants
-  ) {
+    public static bool TryConvertToAutoDiff(ISymbolicExpressionTree tree, bool addLinearScalingTerms, IEnumerable<DataForVariable> variables,
+      out IParametricCompiledTerm autoDiffTerm, out double[] initialConstants) {
       // use a transformator object which holds the state (variable list, parameter list, ...) for recursive transformation of the tree
-      var transformator = new TreeToAutoDiffTermConverter(makeVariableWeightsVariable, parameters);
+      //TODO change ctor
+      var transformator = new TreeToAutoDiffTermConverter(true);
+      var parameters = new AutoDiff.Variable[variables.Count()];
+
+      int i = 0;
+      foreach(var variable in variables) { 
+        var autoDiffVar = new AutoDiff.Variable();
+        transformator.parameters.Add(variable, autoDiffVar);
+        parameters[i] = autoDiffVar;
+        i++;
+      }
+
       AutoDiff.Term term;
       try {
-
-
+        term = transformator.ConvertToAutoDiff(tree.Root.GetSubtree(0));
         if (addLinearScalingTerms) {
-          // scaling variables α, β are given at the beginning of the parameter vector
+          // scaling variables α, β are given at the end of the parameter vector
           var alpha = new AutoDiff.Variable();
           var beta = new AutoDiff.Variable();
+
+          term = term * alpha + beta;
+
+          transformator.variables.Add(alpha);
           transformator.variables.Add(beta);
-          transformator.variables.Add(alpha);
-          term = transformator.ConvertToAutoDiff(tree.Root.GetSubtree(0));
-          term = term * alpha + beta;
-        } else {
-          term = transformator.ConvertToAutoDiff(tree.Root.GetSubtree(0));
-        }
-
-        var compiledTerm = term.Compile(transformator.variables.ToArray(), parameters.Values.ToArray());
-        func = (vars, @params) => compiledTerm.Evaluate(vars, @params);
-        func_grad = (vars, @params) => compiledTerm.Differentiate(vars, @params);
+
+          transformator.initialConstants.Add(1.0);
+          transformator.initialConstants.Add(0.0);
+        }
+
+        var compiledTerm = term.Compile(transformator.variables.ToArray(), parameters);
+        autoDiffTerm = compiledTerm;
         initialConstants = transformator.initialConstants.ToArray();
 
         return true;
       } catch (ConversionException) {
-        func = null;
-        func_grad = null;
+        autoDiffTerm = null;
         initialConstants = null;
       }
@@ -174,11 +181,8 @@
     private readonly bool makeVariableWeightsVariable;
 
-    private TreeToAutoDiffTermConverter(bool makeVariableWeightsVariable, Dictionary<DataForVariable, AutoDiff.Variable> parameters = null) {
+    private TreeToAutoDiffTermConverter(bool makeVariableWeightsVariable) {
       this.makeVariableWeightsVariable = makeVariableWeightsVariable;
       this.initialConstants = new List<double>();
-      if (parameters == null)
-        this.parameters = new Dictionary<DataForVariable, AutoDiff.Variable>();
-      else
-        this.parameters = parameters;
+      this.parameters = new Dictionary<DataForVariable, AutoDiff.Variable>();
       this.variables = new List<AutoDiff.Variable>();
     }
Index: branches/2974_Constants_Optimization/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj
===================================================================
--- branches/2974_Constants_Optimization/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj	(revision 16464)
+++ branches/2974_Constants_Optimization/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj	(revision 16500)
@@ -213,4 +213,6 @@
       <SubType>Code</SubType>
     </Compile>
+    <Compile Include="Constants Optimization\IConstantsOptimizer.cs" />
+    <Compile Include="Constants Optimization\LMConstantsOptimizer.cs" />
     <Compile Include="Constants Optimization\Util.cs" />
     <Compile Include="Converters\LinearModelToTreeConverter.cs" />
Index: branches/2974_Constants_Optimization/UnitTests/ConstantsOptimizationTests.cs
===================================================================
--- branches/2974_Constants_Optimization/UnitTests/ConstantsOptimizationTests.cs	(revision 16464)
+++ branches/2974_Constants_Optimization/UnitTests/ConstantsOptimizationTests.cs	(revision 16500)
@@ -20,15 +20,5 @@
 #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.Optimization;
-using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-using HeuristicLab.Persistence.Default.Xml;
 using HeuristicLab.Problems.DataAnalysis;
 using HeuristicLab.Problems.DataAnalysis.Symbolic;
@@ -38,8 +28,5 @@
 
 using HeuristicLab.Problems.Instances.DataAnalysis;
-
-using System;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
-using HeuristicLab.Algorithms.OffspringSelectionGeneticAlgorithm;
 
 namespace UnitTests {
@@ -57,18 +44,20 @@
 
       var new_optimizedTree = (ISymbolicExpressionTree)tree.Clone();
-      var new_result = ConstantsOptimizationEvaluator.OptimizeConstants(
-        new SymbolicDataAnalysisExpressionTreeLinearInterpreter(),
-        new_optimizedTree, problemData, problemData.TrainingIndices, applyLinearScaling: true, maxIterations: 10);
+      var new_result = LMConstantsOptimizer.OptimizeConstants(new_optimizedTree, problemData, problemData.TrainingIndices, applyLinearScaling: true, maxIterations: 10);
 
       //check R² values
-      Assert.AreEqual(old_result, new_result);
+      //Assert.AreEqual(old_result, new_result);
 
       //check numeric values of constants
       var old_constants = Util.ExtractConstants(old_optimizedTree);
       var new_constants = Util.ExtractConstants(new_optimizedTree);
-      Assert.IsTrue(old_constants.SequenceEqual(new_constants));
-    }
-
-   
+      //Assert.IsTrue(old_constants.SequenceEqual(new_constants));
+
+      for (int i = 0; i < old_constants.Length; i++) {
+        Assert.AreEqual(old_constants[i], new_constants[i], 0.00000001);
+      }
+    }
+
+
 
     [TestMethod]
Index: branches/2974_Constants_Optimization/UnitTests/PerformanceTest.cs
===================================================================
--- branches/2974_Constants_Optimization/UnitTests/PerformanceTest.cs	(revision 16464)
+++ branches/2974_Constants_Optimization/UnitTests/PerformanceTest.cs	(revision 16500)
@@ -1,205 +1,127 @@
 ﻿using System;
-using HeuristicLab.Algorithms.OffspringSelectionGeneticAlgorithm;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
-using HeuristicLab.Persistence.Default.Xml;
+using HeuristicLab.Problems.DataAnalysis;
 using HeuristicLab.Problems.DataAnalysis.Symbolic;
 using HeuristicLab.Problems.DataAnalysis.Symbolic.Regression;
-using HeuristicLab.Selection;
+using HeuristicLab.Problems.Instances.DataAnalysis;
+using HeuristicLab.Random;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
-using System.Linq;
-using HeuristicLab.Problems.Instances.DataAnalysis;
-using HeuristicLab.Problems.DataAnalysis;
-using HeuristicLab.Optimization;
-using HeuristicLab.ParallelEngine;
 
 namespace UnitTests {
   [TestClass]
   public class PerformanceTest {
-    private static int seed = 1234;
+    private static readonly int seed = 1234;
+    private static readonly int totalRows = 1000;
+    private static readonly int maxIterations = 10;
+    private static readonly int repetitions = 5;
+    private static readonly int maxTreeSize = 50;
 
-    //TODO remove performance test 
     [TestMethod]
     [TestCategory("Problems.DataAnalysis.Symbolic.Regression")]
     [TestProperty("Time", "long")]
-    public void ConstantsOptimization_Tower_Algorithm() {
-      var algorithm = CreateGpSymbolicRegressionSample();
-      var problem = (SymbolicRegressionSingleObjectiveProblem)algorithm.Problem;
+    public void New_ConstantsOptimization_Tower_Algorithm() {
+      var twister = new MersenneTwister((uint)seed);
+      var problemData = new RegressionRealWorldInstanceProvider().LoadData(new Tower());
+      var rows = Enumerable.Range(0, totalRows);
 
-      algorithm.MaximumGenerations.Value = 1;
-      var evaluator = new ConstantsOptimizationEvaluator();
-      evaluator.ConstantOptimizationIterations.Value = 5;
-      problem.EvaluatorParameter.Value = evaluator;
-
-      algorithm.Prepare();
-      algorithm.Start();
-    }
-
-    private OffspringSelectionGeneticAlgorithm CreateGpSymbolicRegressionSample() {
-      var osga = new OffspringSelectionGeneticAlgorithm();
-      #region Problem Configuration
-      var provider = new RegressionRealWorldInstanceProvider();
-      var problemData =  provider.LoadData(new Tower());
-      var problem = new SymbolicRegressionSingleObjectiveProblem();
-      problem.ProblemData = problemData;
-      problem.Load(problemData);
-      problem.BestKnownQuality.Value = 1.0;
-
-      #region configure grammar
-
-      var grammar = (TypeCoherentExpressionGrammar)problem.SymbolicExpressionTreeGrammar;
+      var grammar = new TypeCoherentExpressionGrammar();
       grammar.ConfigureAsDefaultRegressionGrammar();
 
-      //symbols square, power, squareroot, root, log, exp, sine, cosine, tangent, variable
-      var square = grammar.Symbols.OfType<Square>().Single();
-      var power = grammar.Symbols.OfType<Power>().Single();
-      var squareroot = grammar.Symbols.OfType<SquareRoot>().Single();
-      var root = grammar.Symbols.OfType<Root>().Single();
-      var cube = grammar.Symbols.OfType<Cube>().Single();
-      var cuberoot = grammar.Symbols.OfType<CubeRoot>().Single();
-      var log = grammar.Symbols.OfType<Logarithm>().Single();
-      var exp = grammar.Symbols.OfType<Exponential>().Single();
-      var sine = grammar.Symbols.OfType<Sine>().Single();
-      var cosine = grammar.Symbols.OfType<Cosine>().Single();
-      var tangent = grammar.Symbols.OfType<Tangent>().Single();
-      var variable = grammar.Symbols.OfType<HeuristicLab.Problems.DataAnalysis.Symbolic.Variable>().Single();
-      var powerSymbols = grammar.Symbols.Single(s => s.Name == "Power Functions");
-      powerSymbols.Enabled = true;
+      var trees = CreateRandomTrees(twister, problemData.Dataset, grammar, 1000, 1, maxTreeSize, 0, 0);
+      foreach (SymbolicExpressionTree tree in trees) {
+        InitTree(tree, twister, problemData.AllowedInputVariables.ToList());
+      }
 
-      square.Enabled = true;
-      square.InitialFrequency = 1.0;
-      foreach (var allowed in grammar.GetAllowedChildSymbols(square))
-        grammar.RemoveAllowedChildSymbol(square, allowed);
-      foreach (var allowed in grammar.GetAllowedChildSymbols(square, 0))
-        grammar.RemoveAllowedChildSymbol(square, allowed, 0);
-      grammar.AddAllowedChildSymbol(square, variable);
+      Console.WriteLine("Random tree constants optimization performance of new method:");
 
-      power.Enabled = false;
+      //warm up
+      for (int i = 0; i < trees.Length; i++) {
+        double quality = LMConstantsOptimizer.OptimizeConstants(trees[i], problemData, rows, true, maxIterations);
+      }
 
-      squareroot.Enabled = false;
-      foreach (var allowed in grammar.GetAllowedChildSymbols(squareroot))
-        grammar.RemoveAllowedChildSymbol(squareroot, allowed);
-      foreach (var allowed in grammar.GetAllowedChildSymbols(squareroot, 0))
-        grammar.RemoveAllowedChildSymbol(squareroot, allowed, 0);
-      grammar.AddAllowedChildSymbol(squareroot, variable);
+      Stopwatch watch = new Stopwatch();
+      for (int rep = 0; rep < repetitions; rep++) {
+        watch.Start();
+        for (int i = 0; i < trees.Length; i++) {
+          double quality = LMConstantsOptimizer.OptimizeConstants(trees[i], problemData, rows, true, maxIterations);
+        }
+        watch.Stop();
+        Console.WriteLine("Iteration " + rep + "\t\t" + " Elapsed time: \t" + watch.ElapsedMilliseconds + " ms \t\t" +
+          "Time per tree: " + watch.ElapsedMilliseconds / 1000.0 / trees.Length);
+        watch.Reset();
+      }
+    }
+    [TestMethod]
+    [TestCategory("Problems.DataAnalysis.Symbolic.Regression")]
+    [TestProperty("Time", "long")]
+    public void Old_ConstantsOptimization_Tower_Algorithm() {
+      var twister = new MersenneTwister((uint)seed);
+      var problemData = new RegressionRealWorldInstanceProvider().LoadData(new Tower());
+      var rows = Enumerable.Range(0, totalRows);
 
-      cube.Enabled = false;
-      cuberoot.Enabled = false;
-      root.Enabled = false;
+      var grammar = new TypeCoherentExpressionGrammar();
+      grammar.ConfigureAsDefaultRegressionGrammar();
 
-      log.Enabled = true;
-      log.InitialFrequency = 1.0;
-      foreach (var allowed in grammar.GetAllowedChildSymbols(log))
-        grammar.RemoveAllowedChildSymbol(log, allowed);
-      foreach (var allowed in grammar.GetAllowedChildSymbols(log, 0))
-        grammar.RemoveAllowedChildSymbol(log, allowed, 0);
-      grammar.AddAllowedChildSymbol(log, variable);
+      var trees = CreateRandomTrees(twister, problemData.Dataset, grammar, 1000, 1, maxTreeSize, 0, 0);
+      foreach (SymbolicExpressionTree tree in trees) {
+        InitTree(tree, twister, problemData.AllowedInputVariables.ToList());
+      }
 
-      exp.Enabled = true;
-      exp.InitialFrequency = 1.0;
-      foreach (var allowed in grammar.GetAllowedChildSymbols(exp))
-        grammar.RemoveAllowedChildSymbol(exp, allowed);
-      foreach (var allowed in grammar.GetAllowedChildSymbols(exp, 0))
-        grammar.RemoveAllowedChildSymbol(exp, allowed, 0);
-      grammar.AddAllowedChildSymbol(exp, variable);
+      Console.WriteLine("Random tree constants optimization performance of existing method:");
+      var interpreter = new SymbolicDataAnalysisExpressionTreeLinearInterpreter();
 
-      sine.Enabled = false;
-      foreach (var allowed in grammar.GetAllowedChildSymbols(sine))
-        grammar.RemoveAllowedChildSymbol(sine, allowed);
-      foreach (var allowed in grammar.GetAllowedChildSymbols(sine, 0))
-        grammar.RemoveAllowedChildSymbol(sine, allowed, 0);
-      grammar.AddAllowedChildSymbol(sine, variable);
+      //warm up
+      for (int i = 0; i < trees.Length; i++) {
+        double quality = SymbolicRegressionConstantOptimizationEvaluator.OptimizeConstants(
+          interpreter, trees[i], problemData, rows, true, maxIterations);
+      }
 
-      cosine.Enabled = false;
-      foreach (var allowed in grammar.GetAllowedChildSymbols(cosine))
-        grammar.RemoveAllowedChildSymbol(cosine, allowed);
-      foreach (var allowed in grammar.GetAllowedChildSymbols(cosine, 0))
-        grammar.RemoveAllowedChildSymbol(cosine, allowed, 0);
-      grammar.AddAllowedChildSymbol(cosine, variable);
-
-      tangent.Enabled = false;
-      foreach (var allowed in grammar.GetAllowedChildSymbols(tangent))
-        grammar.RemoveAllowedChildSymbol(tangent, allowed);
-      foreach (var allowed in grammar.GetAllowedChildSymbols(tangent, 0))
-        grammar.RemoveAllowedChildSymbol(tangent, allowed, 0);
-      grammar.AddAllowedChildSymbol(tangent, variable);
-      #endregion
-
-      problem.SymbolicExpressionTreeGrammar = grammar;
-
-      // configure remaining problem parameters
-      problem.MaximumSymbolicExpressionTreeLength.Value = 50;
-      problem.MaximumSymbolicExpressionTreeDepth.Value = 12;
-      problem.MaximumFunctionDefinitions.Value = 0;
-      problem.MaximumFunctionArguments.Value = 0;
-
-      var evaluator = new SymbolicRegressionConstantOptimizationEvaluator();
-      evaluator.ConstantOptimizationIterations.Value = 5;
-      problem.EvaluatorParameter.Value = evaluator;
-      problem.RelativeNumberOfEvaluatedSamplesParameter.Hidden = true;
-      problem.SolutionCreatorParameter.Hidden = true;
-      #endregion
-
-      #region Algorithm Configuration
-      osga.Problem = problem;
-      osga.Name = "Offspring Selection Genetic Programming - Symbolic Regression";
-      osga.Description = "Genetic programming with strict offspring selection for solving a benchmark regression problem.";
-      ConfigureOsGeneticAlgorithmParameters<GenderSpecificSelector, SubtreeCrossover, MultiSymbolicExpressionTreeManipulator>(osga, 100, 1, 25, 0.2, 50);
-      var mutator = (MultiSymbolicExpressionTreeManipulator)osga.Mutator;
-      mutator.Operators.OfType<FullTreeShaker>().Single().ShakingFactor = 0.1;
-      mutator.Operators.OfType<OnePointShaker>().Single().ShakingFactor = 1.0;
-
-      osga.Analyzer.Operators.SetItemCheckedState(
-        osga.Analyzer.Operators
-          .OfType<SymbolicRegressionSingleObjectiveOverfittingAnalyzer>()
-          .Single(), false);
-      osga.Analyzer.Operators.SetItemCheckedState(
-        osga.Analyzer.Operators
-          .OfType<SymbolicDataAnalysisAlleleFrequencyAnalyzer>()
-          .First(), false);
-
-      osga.ComparisonFactorModifierParameter.Hidden = true;
-      osga.ComparisonFactorLowerBoundParameter.Hidden = true;
-      osga.ComparisonFactorUpperBoundParameter.Hidden = true;
-      osga.OffspringSelectionBeforeMutationParameter.Hidden = true;
-      osga.SuccessRatioParameter.Hidden = true;
-      osga.SelectedParentsParameter.Hidden = true;
-      osga.ElitesParameter.Hidden = true;
-
-      #endregion
-      return osga;
+      Stopwatch watch = new Stopwatch();
+      for (int rep = 0; rep < repetitions; rep++) {
+        watch.Start();
+        for (int i = 0; i < trees.Length; i++) {
+          double quality = SymbolicRegressionConstantOptimizationEvaluator.OptimizeConstants(
+            interpreter, trees[i], problemData, rows, true, maxIterations);
+        }
+        watch.Stop();
+        Console.WriteLine("Iteration " + rep + "\t\t" + " Elapsed time: \t" + watch.ElapsedMilliseconds + " ms \t\t" +
+          "Time per tree: " + watch.ElapsedMilliseconds / 1000.0 / trees.Length);
+        watch.Reset();
+      }
     }
 
 
-    public static void ConfigureOsGeneticAlgorithmParameters<S, C, M>(OffspringSelectionGeneticAlgorithm ga, int popSize, int elites, int maxGens, double mutationRate = 0.05, double maxSelPres = 100, int tournGroupSize = 0)
-      where S : ISelector
-      where C : ICrossover
-      where M : IManipulator {
-      ga.Elites.Value = elites;
-      ga.MaximumGenerations.Value = maxGens;
-      ga.MutationProbability.Value = mutationRate;
-      ga.PopulationSize.Value = popSize;
-      ga.MaximumSelectionPressure.Value = maxSelPres;
-      ga.Seed.Value = 0;
-      ga.SetSeedRandomly.Value = true;
-      ga.ComparisonFactorLowerBound.Value = 1;
-      ga.ComparisonFactorUpperBound.Value = 1;
 
-      ga.Selector = ga.SelectorParameter.ValidValues
-        .OfType<S>()
-        .First();
+    public static ISymbolicExpressionTree[] CreateRandomTrees(MersenneTwister twister, IDataset dataset, ISymbolicExpressionGrammar grammar, int popSize) {
+      return CreateRandomTrees(twister, dataset, grammar, popSize, 1, 200, 3, 3);
+    }
 
-      ga.Crossover = ga.CrossoverParameter.ValidValues
-        .OfType<C>()
-        .First();
+    public static ISymbolicExpressionTree[] CreateRandomTrees(MersenneTwister twister, IDataset dataset, ISymbolicExpressionGrammar grammar,
+      int popSize, int minSize, int maxSize,
+      int maxFunctionDefinitions, int maxFunctionArguments) {
+      foreach (Variable variableSymbol in grammar.Symbols.OfType<Variable>()) {
+        variableSymbol.VariableNames = dataset.VariableNames;
+      }
+      ISymbolicExpressionTree[] randomTrees = new ISymbolicExpressionTree[popSize];
+      for (int i = 0; i < randomTrees.Length; i++) {
+        randomTrees[i] = ProbabilisticTreeCreator.Create(twister, grammar, maxSize, 10);
+      }
+      return randomTrees;
+    }
 
-      ga.Mutator = ga.MutatorParameter.ValidValues
-        .OfType<M>()
-        .First();
-
-      var tSelector = ga.Selector as TournamentSelector;
-      if (tSelector != null) {
-        tSelector.GroupSizeParameter.Value.Value = tournGroupSize;
+    public static void InitTree(ISymbolicExpressionTree tree, MersenneTwister twister, List<string> varNames) {
+      foreach (var node in tree.IterateNodesPostfix()) {
+        if (node is VariableTreeNode) {
+          var varNode = node as VariableTreeNode;
+          varNode.Weight = twister.NextDouble() * 20.0 - 10.0;
+          varNode.VariableName = varNames[twister.Next(varNames.Count)];
+        } else if (node is ConstantTreeNode) {
+          var constantNode = node as ConstantTreeNode;
+          constantNode.Value = twister.NextDouble() * 20.0 - 10.0;
+        }
       }
-      ga.Engine = new ParallelEngine();
     }
 
