Index: trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/BestValidationSymbolicRegressionSolutionVisualizer.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/BestValidationSymbolicRegressionSolutionVisualizer.cs	(revision 3512)
+++ trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/BestValidationSymbolicRegressionSolutionVisualizer.cs	(revision 3513)
@@ -40,4 +40,6 @@
   public sealed class BestValidationSymbolicRegressionSolutionVisualizer : SingleSuccessorOperator, ISingleObjectiveSolutionsVisualizer, ISolutionsVisualizer {
     private const string SymbolicExpressionTreeInterpreterParameterName = "SymbolicExpressionTreeInterpreter";
+    private const string UpperEstimationLimitParameterName = "UpperEstimationLimit";
+    private const string LowerEstimationLimitParameterName = "LowerEstimationLimit";
     private const string SymbolicRegressionModelParameterName = "SymbolicRegressionModel";
     private const string DataAnalysisProblemDataParameterName = "DataAnalysisProblemData";
@@ -51,4 +53,10 @@
     public ILookupParameter<ISymbolicExpressionTreeInterpreter> SymbolicExpressionTreeInterpreterParameter {
       get { return (ILookupParameter<ISymbolicExpressionTreeInterpreter>)Parameters[SymbolicExpressionTreeInterpreterParameterName]; }
+    }
+    public IValueLookupParameter<DoubleValue> UpperEstimationLimitParameter {
+      get { return (IValueLookupParameter<DoubleValue>)Parameters[UpperEstimationLimitParameterName]; }
+    }
+    public IValueLookupParameter<DoubleValue> LowerEstimationLimitParameter {
+      get { return (IValueLookupParameter<DoubleValue>)Parameters[LowerEstimationLimitParameterName]; }
     }
     public IValueLookupParameter<IntValue> ValidationSamplesStartParameter {
@@ -85,4 +93,10 @@
       get { return SymbolicExpressionTreeInterpreterParameter.ActualValue; }
     }
+    public DoubleValue UpperEstimationLimit {
+      get { return UpperEstimationLimitParameter.ActualValue; }
+    }
+    public DoubleValue LowerEstimationLimit {
+      get { return LowerEstimationLimitParameter.ActualValue; }
+    }
     public IntValue ValidationSamplesStart {
       get { return ValidationSamplesStartParameter.ActualValue; }
@@ -99,4 +113,6 @@
       Parameters.Add(new LookupParameter<DataAnalysisProblemData>(DataAnalysisProblemDataParameterName, "The symbolic regression problme data on which the best solution should be evaluated."));
       Parameters.Add(new LookupParameter<ISymbolicExpressionTreeInterpreter>(SymbolicExpressionTreeInterpreterParameterName, "The interpreter that should be used to calculate the output values of symbolic expression trees."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>(UpperEstimationLimitParameterName, "The upper limit that should be used as cut off value for the output values of symbolic expression trees."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>(LowerEstimationLimitParameterName, "The lower limit that should be used as cut off value for the output values of symbolic expression trees."));
       Parameters.Add(new ValueLookupParameter<IntValue>(ValidationSamplesStartParameterName, "The start index of the validation partition (part of the training partition)."));
       Parameters.Add(new ValueLookupParameter<IntValue>(ValidationSamplesEndParameterName, "The end index of the validation partition (part of the training partition)."));
@@ -112,9 +128,11 @@
       int validationSamplesEnd = ValidationSamplesEnd.Value;
       var validationValues = problemData.Dataset.GetVariableValues(problemData.TargetVariable.Value, validationSamplesStart, validationSamplesEnd);
-
+      double upperEstimationLimit = UpperEstimationLimit.Value;
+      double lowerEstimationLimit = LowerEstimationLimit.Value;
       var currentBestExpression = (from expression in expressions
                                    let validationQuality =
                                      SymbolicRegressionMeanSquaredErrorEvaluator.Calculate(
                                        SymbolicExpressionTreeInterpreter, expression,
+                                       lowerEstimationLimit, upperEstimationLimit,
                                        problemData.Dataset, problemData.TargetVariable.Value,
                                        validationSamplesStart, validationSamplesEnd)
@@ -126,5 +144,5 @@
       if (bestOfRunSolution == null) {
         // no best of run solution yet -> make a solution from the currentBestExpression
-        UpdateBestOfRunSolution(problemData, currentBestExpression.Expression, SymbolicExpressionTreeInterpreter);
+        UpdateBestOfRunSolution(problemData, currentBestExpression.Expression, SymbolicExpressionTreeInterpreter, lowerEstimationLimit, upperEstimationLimit);
       } else {
         // compare quality of current best with best of run solution
@@ -132,5 +150,5 @@
         var bestOfRunValidationQuality = SimpleMSEEvaluator.Calculate(validationValues, estimatedValidationValues);
         if (bestOfRunValidationQuality > currentBestExpression.ValidationQuality) {
-          UpdateBestOfRunSolution(problemData, currentBestExpression.Expression, SymbolicExpressionTreeInterpreter);
+          UpdateBestOfRunSolution(problemData, currentBestExpression.Expression, SymbolicExpressionTreeInterpreter, lowerEstimationLimit, upperEstimationLimit);
         }
       }
@@ -140,6 +158,7 @@
     }
 
-    private void UpdateBestOfRunSolution(DataAnalysisProblemData problemData, SymbolicExpressionTree tree, ISymbolicExpressionTreeInterpreter interpreter) {
-      var newBestSolution = CreateDataAnalysisSolution(problemData, tree, interpreter);
+    private void UpdateBestOfRunSolution(DataAnalysisProblemData problemData, SymbolicExpressionTree tree, ISymbolicExpressionTreeInterpreter interpreter,
+      double lowerEstimationLimit, double upperEstimationLimit) {
+      var newBestSolution = CreateDataAnalysisSolution(problemData, tree, interpreter, lowerEstimationLimit, upperEstimationLimit);
       if (BestValidationSolutionParameter.ActualValue == null)
         BestValidationSolutionParameter.ActualValue = newBestSolution;
@@ -169,7 +188,8 @@
     }
 
-    private SymbolicRegressionSolution CreateDataAnalysisSolution(DataAnalysisProblemData problemData, SymbolicExpressionTree expression, ISymbolicExpressionTreeInterpreter interpreter) {
+    private SymbolicRegressionSolution CreateDataAnalysisSolution(DataAnalysisProblemData problemData, SymbolicExpressionTree expression, ISymbolicExpressionTreeInterpreter interpreter,
+      double lowerEstimationLimit, double upperEstimationLimit) {
       var model = new SymbolicRegressionModel(interpreter, expression, problemData.InputVariables.Select(s => s.Value));
-      return new SymbolicRegressionSolution(problemData, model);
+      return new SymbolicRegressionSolution(problemData, model, lowerEstimationLimit, upperEstimationLimit);
     }
   }
Index: trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/SymbolicRegressionMeanSquaredErrorEvaluator.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/SymbolicRegressionMeanSquaredErrorEvaluator.cs	(revision 3512)
+++ trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/SymbolicRegressionMeanSquaredErrorEvaluator.cs	(revision 3513)
@@ -41,12 +41,39 @@
   [StorableClass]
   public class SymbolicRegressionMeanSquaredErrorEvaluator : SymbolicRegressionEvaluator {
+    private const string UpperEstimationLimitParameterName = "UpperEstimationLimit";
+    private const string LowerEstimationLimitParameterName = "LowerEstimationLimit";
+
+    #region parameter properties
+    public IValueLookupParameter<DoubleValue> UpperEstimationLimitParameter {
+      get { return (IValueLookupParameter<DoubleValue>)Parameters[UpperEstimationLimitParameterName]; }
+    }
+    public IValueLookupParameter<DoubleValue> LowerEstimationLimitParameter {
+      get { return (IValueLookupParameter<DoubleValue>)Parameters[LowerEstimationLimitParameterName]; }
+    }
+    #endregion
+    #region properties
+    public DoubleValue UpperEstimationLimit {
+      get { return UpperEstimationLimitParameter.ActualValue; }
+    }
+    public DoubleValue LowerEstimationLimit {
+      get { return LowerEstimationLimitParameter.ActualValue; }
+    }
+    #endregion
+    public SymbolicRegressionMeanSquaredErrorEvaluator()
+      : base() {
+      Parameters.Add(new ValueLookupParameter<DoubleValue>(UpperEstimationLimitParameterName, "The upper limit that should be used as cut off value for the output values of symbolic expression trees."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>(LowerEstimationLimitParameterName, "The lower limit that should be used as cut off value for the output values of symbolic expression trees."));
+    }
+
     protected override double Evaluate(ISymbolicExpressionTreeInterpreter interpreter, SymbolicExpressionTree solution, Dataset dataset, StringValue targetVariable, IntValue samplesStart, IntValue samplesEnd) {
-      double mse = Calculate(interpreter, solution, dataset, targetVariable.Value, samplesStart.Value, samplesEnd.Value);
+      double mse = Calculate(interpreter, solution, LowerEstimationLimit.Value, UpperEstimationLimit.Value, dataset, targetVariable.Value, samplesStart.Value, samplesEnd.Value);
       return mse;
     }
 
-    public static double Calculate(ISymbolicExpressionTreeInterpreter interpreter, SymbolicExpressionTree solution, Dataset dataset, string targetVariable, int start, int end) {
+    public static double Calculate(ISymbolicExpressionTreeInterpreter interpreter, SymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, Dataset dataset, string targetVariable, int start, int end) {
       int targetVariableIndex = dataset.GetVariableIndex(targetVariable);
-      var estimatedValues = interpreter.GetSymbolicExpressionTreeValues(solution, dataset, Enumerable.Range(start, end - start));
+      var estimatedValues = from x in interpreter.GetSymbolicExpressionTreeValues(solution, dataset, Enumerable.Range(start, end - start))
+                            let boundedX = Math.Min(upperEstimationLimit, Math.Max(lowerEstimationLimit, x))
+                            select double.IsNaN(boundedX) ? upperEstimationLimit : boundedX;
       var originalValues = from row in Enumerable.Range(start, end - start) select dataset[row, targetVariableIndex];
       return SimpleMSEEvaluator.Calculate(originalValues, estimatedValues);
Index: trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/SymbolicRegressionModel.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/SymbolicRegressionModel.cs	(revision 3512)
+++ trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/SymbolicRegressionModel.cs	(revision 3513)
@@ -55,5 +55,4 @@
       get { return inputVariables.AsEnumerable(); }
     }
-
     public SymbolicRegressionModel() : base() { } // for cloning
 
Index: trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/SymbolicRegressionProblem.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/SymbolicRegressionProblem.cs	(revision 3512)
+++ trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/SymbolicRegressionProblem.cs	(revision 3513)
@@ -58,4 +58,13 @@
       get { return SolutionCreatorParameter; }
     }
+    public ValueParameter<DoubleValue> LowerEstimationLimitParameter {
+      get { return (ValueParameter<DoubleValue>)Parameters["LowerEstimationLimit"]; }
+    }
+    public ValueParameter<DoubleValue> UpperEstimationLimitParameter {
+      get { return (ValueParameter<DoubleValue>)Parameters["UpperEstimationLimit"]; }
+    }
+    public ValueParameter<ISymbolicExpressionTreeInterpreter> SymbolicExpressionTreeInterpreterParameter {
+      get { return (ValueParameter<ISymbolicExpressionTreeInterpreter>)Parameters["SymbolicExpressionTreeInterpreter"]; }
+    }
     public ValueParameter<ISymbolicRegressionEvaluator> EvaluatorParameter {
       get { return (ValueParameter<ISymbolicRegressionEvaluator>)Parameters["Evaluator"]; }
@@ -109,4 +118,17 @@
       get { return SolutionCreatorParameter.Value; }
     }
+    public ISymbolicExpressionTreeInterpreter SymbolicExpressionTreeInterpreter {
+      get { return SymbolicExpressionTreeInterpreterParameter.Value; }
+      set { SymbolicExpressionTreeInterpreterParameter.Value = value; }
+    }
+    public DoubleValue LowerEstimationLimit {
+      get { return LowerEstimationLimitParameter.Value; }
+      set { LowerEstimationLimitParameter.Value = value; }
+    }
+    public DoubleValue UpperEstimationLimit {
+      get { return UpperEstimationLimitParameter.Value; }
+      set { UpperEstimationLimitParameter.Value = value; }
+    }
+
     public ISymbolicRegressionEvaluator Evaluator {
       get { return EvaluatorParameter.Value; }
@@ -135,4 +157,7 @@
     public IEnumerable<IOperator> Operators {
       get { return operators.Cast<IOperator>(); }
+    }
+    public DoubleValue PunishmentFactor {
+      get { return new DoubleValue(10.0); }
     }
     #endregion
@@ -150,4 +175,6 @@
       Parameters.Add(new ValueParameter<ISymbolicExpressionTreeInterpreter>("SymbolicExpressionTreeInterpreter", "The interpreter that should be used to evaluate the symbolic expression tree.", interpreter));
       Parameters.Add(new ValueParameter<ISymbolicRegressionEvaluator>("Evaluator", "The operator which should be used to evaluate symbolic regression solutions.", evaluator));
+      Parameters.Add(new ValueParameter<DoubleValue>("LowerEstimationLimit", "The lower limit for the estimated value that can be returned by the symbolic regression model.", new DoubleValue(double.NegativeInfinity)));
+      Parameters.Add(new ValueParameter<DoubleValue>("UpperEstimationLimit", "The upper limit for the estimated value that can be returned by the symbolic regression model.", new DoubleValue(double.PositiveInfinity)));
       Parameters.Add(new OptionalValueParameter<DoubleValue>("BestKnownQuality", "The minimal error value that reached by symbolic regression solutions for the problem."));
       Parameters.Add(new ValueParameter<ISymbolicExpressionGrammar>("FunctionTreeGrammar", "The grammar that should be used for symbolic regression models.", globalGrammar));
@@ -169,5 +196,4 @@
       Initialize();
     }
-
 
     [StorableConstructor]
@@ -208,4 +234,12 @@
       Evaluator.SamplesStartParameter.Value = new IntValue(trainingStart);
       Evaluator.SamplesEndParameter.Value = new IntValue(trainingEnd);
+
+      if (trainingEnd - trainingStart > 0 && DataAnalysisProblemData.TargetVariable.Value != string.Empty) {
+        var targetValues = DataAnalysisProblemData.Dataset.GetVariableValues(DataAnalysisProblemData.TargetVariable.Value, trainingStart, trainingEnd);
+        var mean = targetValues.Average();
+        var range = targetValues.Max() - targetValues.Min();
+        UpperEstimationLimit = new DoubleValue(mean + PunishmentFactor.Value * range);
+        LowerEstimationLimit = new DoubleValue(mean - PunishmentFactor.Value * range);
+      }
     }
 
Index: trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/SymbolicRegressionSolution.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/SymbolicRegressionSolution.cs	(revision 3512)
+++ trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/SymbolicRegressionSolution.cs	(revision 3513)
@@ -50,6 +50,6 @@
 
     public SymbolicRegressionSolution() : base() { }
-    public SymbolicRegressionSolution(DataAnalysisProblemData problemData, SymbolicRegressionModel model)
-      : base(problemData) {
+    public SymbolicRegressionSolution(DataAnalysisProblemData problemData, SymbolicRegressionModel model, double lowerEstimationLimit, double upperEstimationLimit)
+      : base(problemData, lowerEstimationLimit, upperEstimationLimit) {
       this.model = model;
     }
@@ -68,5 +68,7 @@
 
     private void RecalculateEstimatedValues() {
-      estimatedValues = model.GetEstimatedValues(ProblemData.Dataset, 0, ProblemData.Dataset.Rows).ToList();
+      estimatedValues = (from x in model.GetEstimatedValues(ProblemData.Dataset, 0, ProblemData.Dataset.Rows)
+                         let boundedX = Math.Min(UpperEstimationLimit, Math.Max(LowerEstimationLimit, x))
+                         select double.IsNaN(boundedX) ? UpperEstimationLimit : boundedX).ToList();
       OnEstimatedValuesChanged(EventArgs.Empty);
     }
Index: trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/DataAnalysisSolution.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/DataAnalysisSolution.cs	(revision 3512)
+++ trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/DataAnalysisSolution.cs	(revision 3513)
@@ -50,4 +50,27 @@
       }
     }
+    [Storable]
+    private double lowerEstimationLimit;
+    public double LowerEstimationLimit {
+      get { return lowerEstimationLimit; }
+      set {
+        if (lowerEstimationLimit != value) {
+          lowerEstimationLimit = value;
+          OnEstimatedValuesChanged(EventArgs.Empty);
+        }
+      }
+    }
+
+    [Storable]
+    private double upperEstimationLimit;
+    public double UpperEstimationLimit {
+      get { return upperEstimationLimit; }
+      set {
+        if (upperEstimationLimit != value) {
+          upperEstimationLimit = value;
+          OnEstimatedValuesChanged(EventArgs.Empty);
+        }
+      }
+    }
 
     public abstract IEnumerable<double> EstimatedValues { get; }
@@ -56,7 +79,10 @@
 
     protected DataAnalysisSolution() : base() { }
-    protected DataAnalysisSolution(DataAnalysisProblemData problemData)
+    protected DataAnalysisSolution(DataAnalysisProblemData problemData) : this(problemData, double.NegativeInfinity, double.PositiveInfinity) { }
+    protected DataAnalysisSolution(DataAnalysisProblemData problemData, double lowerEstimationLimit, double upperEstimationLimit)
       : this() {
       this.problemData = problemData;
+      this.lowerEstimationLimit = lowerEstimationLimit;
+      this.upperEstimationLimit = upperEstimationLimit;
       Initialize();
     }
@@ -74,4 +100,6 @@
       // don't clone the problem data!
       clone.problemData = problemData;
+      clone.lowerEstimationLimit = lowerEstimationLimit;
+      clone.upperEstimationLimit = upperEstimationLimit;
       clone.Initialize();
       return clone;
Index: trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/SimpleArithmeticExpressionInterpreter.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/SimpleArithmeticExpressionInterpreter.cs	(revision 3512)
+++ trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/SimpleArithmeticExpressionInterpreter.cs	(revision 3513)
@@ -34,5 +34,5 @@
   [Item("SimpleArithmeticExpressionInterpreter", "Interpreter for arithmetic symbolic expression trees including function calls.")]
   // not thread safe!
-  public class SimpleArithmeticExpressionInterpreter : Item, ISymbolicExpressionTreeInterpreter {
+  public class SimpleArithmeticExpressionInterpreter : NamedItem, ISymbolicExpressionTreeInterpreter {
     private class OpCodes {
       public const byte Add = 1;
@@ -47,8 +47,13 @@
 
     private const int ARGUMENT_STACK_SIZE = 1024;
+
     private Dataset dataset;
     private int row;
     private Instruction[] code;
     private int pc;
+
+    public SimpleArithmeticExpressionInterpreter()
+      : base() {
+    }
 
     public IEnumerable<double> GetSymbolicExpressionTreeValues(SymbolicExpressionTree tree, Dataset dataset, IEnumerable<int> rows) {
@@ -61,7 +66,5 @@
         pc = 0;
         argStackPointer = 0;
-        var estimatedValue = Evaluate();
-        if (double.IsNaN(estimatedValue) || double.IsInfinity(estimatedValue)) yield return 0.0;
-        else yield return estimatedValue;
+        yield return Evaluate();
       }
     }
