Index: branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression-3.4.csproj
===================================================================
--- trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression-3.4.csproj	(revision 10037)
+++ branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression-3.4.csproj	(revision 10214)
@@ -41,5 +41,5 @@
     <DebugType>full</DebugType>
     <Optimize>false</Optimize>
-    <OutputPath>$(SolutionDir)\bin\</OutputPath>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
     <DefineConstants>DEBUG;TRACE</DefineConstants>
     <ErrorReport>prompt</ErrorReport>
@@ -50,5 +50,5 @@
     <DebugType>pdbonly</DebugType>
     <Optimize>true</Optimize>
-    <OutputPath>$(SolutionDir)\bin\</OutputPath>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
     <DefineConstants>TRACE</DefineConstants>
     <ErrorReport>prompt</ErrorReport>
@@ -58,5 +58,5 @@
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
     <DebugSymbols>true</DebugSymbols>
-    <OutputPath>$(SolutionDir)\bin\</OutputPath>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
     <DefineConstants>DEBUG;TRACE</DefineConstants>
     <DebugType>full</DebugType>
@@ -66,5 +66,5 @@
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
-    <OutputPath>$(SolutionDir)\bin\</OutputPath>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
     <DefineConstants>TRACE</DefineConstants>
     <Optimize>true</Optimize>
@@ -76,5 +76,5 @@
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
     <DebugSymbols>true</DebugSymbols>
-    <OutputPath>$(SolutionDir)\bin\</OutputPath>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
     <DefineConstants>DEBUG;TRACE</DefineConstants>
     <DebugType>full</DebugType>
@@ -84,5 +84,5 @@
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
-    <OutputPath>$(SolutionDir)\bin\</OutputPath>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
     <DefineConstants>TRACE</DefineConstants>
     <Optimize>true</Optimize>
@@ -126,4 +126,5 @@
     <Compile Include="SingleObjective\Evaluators\SymbolicRegressionConstantOptimizationEvaluator.cs" />
     <Compile Include="SingleObjective\SymbolicRegressionSingleObjectiveOverfittingAnalyzer.cs" />
+    <Compile Include="SymbolicDataAnalysisRegressionSolutionPruningOptimizer.cs" />
     <Compile Include="SymbolicRegressionModel.cs" />
     <Compile Include="Interfaces\ISymbolicRegressionModel.cs" />
@@ -194,7 +195,6 @@
     </ProjectReference>
     <ProjectReference Include="..\..\HeuristicLab.Encodings.SymbolicExpressionTreeEncoding\3.4\HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4.csproj">
-      <Project>{06D4A186-9319-48A0-BADE-A2058D462EEA}</Project>
+      <Project>{06d4a186-9319-48a0-bade-a2058d462eea}</Project>
       <Name>HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4</Name>
-      <Private>False</Private>
     </ProjectReference>
     <ProjectReference Include="..\..\HeuristicLab.Operators\3.3\HeuristicLab.Operators-3.3.csproj">
@@ -224,7 +224,6 @@
     </ProjectReference>
     <ProjectReference Include="..\..\HeuristicLab.Problems.DataAnalysis.Symbolic\3.4\HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj">
-      <Project>{3D28463F-EC96-4D82-AFEE-38BE91A0CA00}</Project>
+      <Project>{3d28463f-ec96-4d82-afee-38be91a0ca00}</Project>
       <Name>HeuristicLab.Problems.DataAnalysis.Symbolic-3.4</Name>
-      <Private>False</Private>
     </ProjectReference>
     <ProjectReference Include="..\..\HeuristicLab.Problems.DataAnalysis\3.4\HeuristicLab.Problems.DataAnalysis-3.4.csproj">
Index: branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SymbolicDataAnalysisRegressionSolutionPruningOptimizer.cs
===================================================================
--- branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SymbolicDataAnalysisRegressionSolutionPruningOptimizer.cs	(revision 10214)
+++ branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SymbolicDataAnalysisRegressionSolutionPruningOptimizer.cs	(revision 10214)
@@ -0,0 +1,88 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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.Linq;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.DataAnalysis.Symbolic.Regression;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
+  [Item("SymbolicDataAnalysisSolutionPruningOptimizer", "An operator which automatically removes nodes that have a negative impact from the tree model, optimizing the remaining constants.")]
+  [StorableClass]
+  public class SymbolicDataAnalysisRegressionSolutionPruningOptimizer : SymbolicDataAnalysisSolutionPruningOptimizer {
+    public override ISymbolicDataAnalysisSolution PruneAndOptimizeSolution(ISymbolicDataAnalysisSolution solution) {
+      var regressionSolution = (ISymbolicRegressionSolution)solution;
+      return PruneAndOptimizeRegressionSolution(regressionSolution);
+    }
+    /// <summary>
+    /// This method will walk all the levels of the symbolic regression solution model root starting from the deepest level and:
+    /// - it calculates the impact value of every originalNode on that level
+    /// - it prunes (replaces with a constant) the originalNode with the lowest negative impact value (0 or positive impacts are left unchanged)
+    /// - when no more nodes can be pruned, it moves on the upper level in the tree
+    /// - if the pruned and optimized solution is worse than the original solution (it can happen sometimes), then the original solution is returned
+    /// </summary>
+    /// <param name="solution"></param>
+    /// <returns></returns>
+    private ISymbolicRegressionSolution PruneAndOptimizeRegressionSolution(ISymbolicRegressionSolution solution) {
+      var calculator = new SymbolicRegressionSolutionImpactValuesCalculator();
+      var model = (ISymbolicRegressionModel)solution.Model;
+      var problemData = solution.ProblemData;
+      // get tree levels and iterate each level from the bottom up
+      var root = model.SymbolicExpressionTree.Root.GetSubtree(0).GetSubtree(0);
+      var levels = root.IterateNodesBreadth().GroupBy(root.GetBranchLevel).OrderByDescending(g => g.Key);
+
+      OptimizeConstants(solution); // even if there are no negative impacts we still optimize the solution
+
+      foreach (var level in levels) {
+        var nodes = level.ToArray();
+        double minImpact;
+        do {
+          minImpact = 0.0;
+          int minImpactIndex = -1;
+          for (int i = 0; i < nodes.Length; ++i) {
+            if (nodes[i] is ConstantTreeNode) continue;
+            var impact = calculator.CalculateImpactValue(model, nodes[i], problemData, problemData.TrainingIndices);
+            if (impact < minImpact) {
+              minImpact = impact;
+              minImpactIndex = i;
+            }
+          }
+          if (minImpact >= 0) continue;
+          var node = nodes[minImpactIndex];
+          var replacementValue = calculator.CalculateReplacementValue(model, node, problemData, problemData.TrainingIndices);
+          var constantNode = MakeConstantTreeNode(replacementValue);
+          ReplaceWithConstantNode(node, constantNode);
+          nodes[minImpactIndex] = constantNode;
+          OptimizeConstants(solution);
+        } while (minImpact < 0);
+      }
+
+      var newSolution = (ISymbolicRegressionSolution)model.CreateRegressionSolution(problemData);
+      return newSolution.TrainingRSquared > solution.TrainingRSquared ? newSolution : solution;
+    }
+
+    private static void OptimizeConstants(ISymbolicRegressionSolution solution) {
+      var model = solution.Model;
+      var problemData = solution.ProblemData;
+      SymbolicRegressionConstantOptimizationEvaluator.OptimizeConstants(model.Interpreter, model.SymbolicExpressionTree, problemData, problemData.TrainingIndices, true, 50);
+    }
+  }
+}
