Index: /branches/2974_Constants_Optimization/Benchmarks/Benchmarks.sln
===================================================================
--- /branches/2974_Constants_Optimization/Benchmarks/Benchmarks.sln	(revision 16525)
+++ /branches/2974_Constants_Optimization/Benchmarks/Benchmarks.sln	(revision 16525)
@@ -0,0 +1,25 @@
+﻿
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.28307.271
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Benchmarks", "Benchmarks\Benchmarks.csproj", "{C70B077B-7A10-4093-9293-BF33C9466E68}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{C70B077B-7A10-4093-9293-BF33C9466E68}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{C70B077B-7A10-4093-9293-BF33C9466E68}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{C70B077B-7A10-4093-9293-BF33C9466E68}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{C70B077B-7A10-4093-9293-BF33C9466E68}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+		SolutionGuid = {77E791BC-509D-493B-A171-FC041C72C546}
+	EndGlobalSection
+EndGlobal
Index: /branches/2974_Constants_Optimization/Benchmarks/Benchmarks/Benchmarks.csproj
===================================================================
--- /branches/2974_Constants_Optimization/Benchmarks/Benchmarks/Benchmarks.csproj	(revision 16525)
+++ /branches/2974_Constants_Optimization/Benchmarks/Benchmarks/Benchmarks.csproj	(revision 16525)
@@ -0,0 +1,52 @@
+﻿<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <OutputType>Exe</OutputType>
+    <TargetFrameworks>netcoreapp2.1;net472</TargetFrameworks>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <PackageReference Include="BenchmarkDotNet" Version="0.11.3" />
+    <PackageReference Include="System.Drawing.Common" Version="4.5.1" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <Reference Include="AutoDiff-1.0">
+      <HintPath>..\..\..\..\trunk\bin\AutoDiff-1.0.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Common-3.3">
+      <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Common-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Core-3.3">
+      <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Core-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Data-3.3">
+      <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Data-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4">
+      <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Operators-3.3">
+      <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Operators-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Problems.DataAnalysis-3.4">
+      <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Problems.DataAnalysis-3.4.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Problems.DataAnalysis.Symbolic-3.4">
+      <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Problems.DataAnalysis.Symbolic.Regression-3.4">
+      <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Problems.DataAnalysis.Symbolic.Regression-3.4.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Problems.Instances-3.3">
+      <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Problems.Instances-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Problems.Instances.DataAnalysis-3.3">
+      <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Problems.Instances.DataAnalysis-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Random-3.3">
+      <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Random-3.3.dll</HintPath>
+    </Reference>
+  </ItemGroup>
+
+</Project>
Index: /branches/2974_Constants_Optimization/Benchmarks/Benchmarks/ConstantsOptimizationPerformance.cs
===================================================================
--- /branches/2974_Constants_Optimization/Benchmarks/Benchmarks/ConstantsOptimizationPerformance.cs	(revision 16525)
+++ /branches/2974_Constants_Optimization/Benchmarks/Benchmarks/ConstantsOptimizationPerformance.cs	(revision 16525)
@@ -0,0 +1,70 @@
+﻿using BenchmarkDotNet.Attributes;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Problems.DataAnalysis;
+using HeuristicLab.Problems.DataAnalysis.Symbolic;
+using HeuristicLab.Problems.DataAnalysis.Symbolic.ConstantsOptimization;
+using HeuristicLab.Problems.DataAnalysis.Symbolic.Regression;
+using HeuristicLab.Problems.Instances.DataAnalysis;
+using HeuristicLab.Random;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace HeuristicLab.Benchmarks {
+  [ClrJob]
+  [MinColumn, MaxColumn, MeanColumn, MedianColumn]
+  public class ConstantsOptimizationPerformance {
+    private static readonly int seed = 1234;
+    private static readonly int maxTreeSize = 50;
+    private static readonly int nTrees = 1000;
+
+    private ISymbolicExpressionTree[] trees;
+    private IRegressionProblemData problemData;
+    private TypeCoherentExpressionGrammar grammar;
+    private int[] rows;
+
+    private readonly ISymbolicDataAnalysisExpressionTreeInterpreter interpreter = new SymbolicDataAnalysisExpressionTreeLinearInterpreter();
+
+    [GlobalSetup]
+    public void Setup() {
+      var twister = new MersenneTwister((uint)seed);
+      problemData = new RegressionRealWorldInstanceProvider().LoadData(new Tower());
+      rows = Enumerable.Range(0, Rows).ToArray();
+
+      grammar = new TypeCoherentExpressionGrammar();
+      grammar.ConfigureAsDefaultRegressionGrammar();
+
+      trees = Util.CreateRandomTrees(twister, problemData.Dataset, grammar, nTrees, 1, maxTreeSize, 0, 0);
+      foreach (SymbolicExpressionTree tree in trees) {
+        Util.InitTree(tree, twister, problemData.AllowedInputVariables.ToList());
+      }
+    }
+
+    //public IEnumerable<int> RowsValues => Util.IntRange(100, 5000, 100, closed: true);
+    //public IEnumerable<int> RowsValues => new[] { 100, 250, 500, 750, 1000, 1500, 2000, 3000, 4000, 4999 };
+    public IEnumerable<int> RowsValues => new[] { 4999 };
+    public IEnumerable<int> IterationsValues => Util.IntRange(5, 30, 5, closed: true);
+    //public IEnumerable<int> IterationsValues => new[] { 0 };
+
+    [ParamsSource(nameof(RowsValues))]
+    public int Rows { get; set; }
+
+    [ParamsSource(nameof(IterationsValues))]
+    public int Iterations { get; set; }
+
+    [Benchmark]
+    public double Tower() {
+      double avgQuality = 0;
+
+      if (Iterations > 0) {
+        for (int i = 0; i < trees.Length; i++) {
+          avgQuality += LMConstantsOptimizer.OptimizeConstants(trees[i], problemData.Dataset, problemData.TargetVariable, rows, true, Iterations);
+        }
+      } else {
+        for (int i = 0; i < trees.Length; i++) {
+          avgQuality += SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.Calculate(interpreter, trees[i], double.MinValue, double.MaxValue, problemData, rows, true);
+        }
+      }
+      return avgQuality / trees.Length;
+    }
+  }
+}
Index: /branches/2974_Constants_Optimization/Benchmarks/Benchmarks/Program.cs
===================================================================
--- /branches/2974_Constants_Optimization/Benchmarks/Benchmarks/Program.cs	(revision 16525)
+++ /branches/2974_Constants_Optimization/Benchmarks/Benchmarks/Program.cs	(revision 16525)
@@ -0,0 +1,9 @@
+﻿using BenchmarkDotNet.Running;
+
+namespace HeuristicLab.Benchmarks {
+  internal class Program {
+    private static void Main(string[] args) {
+      var summary = BenchmarkRunner.Run<ConstantsOptimizationPerformance>();
+    }
+  }
+}
Index: /branches/2974_Constants_Optimization/Benchmarks/Benchmarks/Util.cs
===================================================================
--- /branches/2974_Constants_Optimization/Benchmarks/Benchmarks/Util.cs	(revision 16525)
+++ /branches/2974_Constants_Optimization/Benchmarks/Benchmarks/Util.cs	(revision 16525)
@@ -0,0 +1,59 @@
+﻿using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Problems.DataAnalysis;
+using HeuristicLab.Problems.DataAnalysis.Symbolic;
+using HeuristicLab.Random;
+using System.Collections.Generic;
+using System.Linq;
+using Variable = HeuristicLab.Problems.DataAnalysis.Symbolic.Variable;
+
+namespace HeuristicLab.Benchmarks {
+  public static class Util {
+    public static Dataset CreateRandomDataset(IRandom random, int rows, int columns) {
+      double[,] data = new double[rows, columns];
+      for (int i = 0; i < rows; i++) {
+        for (int j = 0; j < columns; j++) {
+          data[i, j] = random.NextDouble() * 2.0 - 1.0;
+        }
+      }
+      IEnumerable<string> variableNames = new string[] { "y" }.Concat(Enumerable.Range(0, columns - 1).Select(x => "x" + x.ToString()));
+      Dataset ds = new Dataset(variableNames, data);
+      return ds;
+    }
+
+    public static IEnumerable<int> IntRange(int start, int end, int step, bool closed = true) {
+      return SequenceGenerator.GenerateSteps((decimal)start, end, step, closed).Select(x => (int)x);
+    }
+
+    public static ISymbolicExpressionTree[] CreateRandomTrees(IRandom twister, IDataset dataset, ISymbolicExpressionGrammar grammar, int popSize) {
+      return CreateRandomTrees(twister, dataset, grammar, popSize, 1, 200, 3, 3);
+    }
+
+    public static ISymbolicExpressionTree[] CreateRandomTrees(IRandom 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;
+    }
+
+    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;
+        }
+      }
+    }
+  }
+}
