Index: /branches/3076_IA_evaluators_analyzers/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression-3.4.csproj
===================================================================
--- /branches/3076_IA_evaluators_analyzers/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression-3.4.csproj	(revision 17743)
+++ /branches/3076_IA_evaluators_analyzers/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression-3.4.csproj	(revision 17744)
@@ -177,8 +177,7 @@
     <Compile Include="SingleObjective\ConstantOptimizationAnalyzer.cs" />
     <Compile Include="SingleObjective\Evaluators\SymbolicRegressionMeanRelativeErrorEvaluator.cs" />
-    <Compile Include="SingleObjective\Evaluators\SymbolicRegressionSingleObjectiveConstraintConstOptEvaluator.cs" />
+    <Compile Include="SingleObjective\Evaluators\SymbolicRegressionSingleObjectiveConstraintEvaluator.cs" />
     <Compile Include="SingleObjective\Evaluators\SymbolicRegressionSingleObjectiveConstraintScalingNmseEvaluator.cs" />
     <Compile Include="SingleObjective\Evaluators\SymbolicRegressionSingleObjectiveConstraintConstOptNmseEvaluator.cs" />
-    <Compile Include="SingleObjective\Evaluators\SymbolicRegressionSingleObjectiveConstraintPearsonRSquaredEvaluator.cs" />
     <Compile Include="SingleObjective\SymbolicRegressionSolutionsAnalyzer.cs" />
     <Compile Include="SymbolicRegressionConstraintAnalyzer.cs" />
Index: anches/3076_IA_evaluators_analyzers/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionSingleObjectiveConstraintConstOptEvaluator.cs
===================================================================
--- /branches/3076_IA_evaluators_analyzers/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionSingleObjectiveConstraintConstOptEvaluator.cs	(revision 17743)
+++ 	(revision )
@@ -1,74 +1,0 @@
-﻿using System.Collections.Generic;
-using HEAL.Attic;
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Data;
-using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
-
-namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Regression {
-  [Item("Constraint ConstOpt Evaluator", "")]
-  [StorableType("4170FD8B-DDD9-43B7-8BF8-F9C7290D4D1C")]
-  public class SymbolicRegressionSingleObjectiveConstraintConstOptEvaluator : SymbolicRegressionSingleObjectiveEvaluator {
-    [StorableConstructor]
-    protected SymbolicRegressionSingleObjectiveConstraintConstOptEvaluator(StorableConstructorFlag _) : base(_) { }
-
-    protected SymbolicRegressionSingleObjectiveConstraintConstOptEvaluator(
-      SymbolicRegressionSingleObjectiveConstraintConstOptEvaluator original, Cloner cloner)
-      : base(original, cloner) { }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new SymbolicRegressionSingleObjectiveConstraintConstOptEvaluator(this, cloner);
-    }
-
-    public SymbolicRegressionSingleObjectiveConstraintConstOptEvaluator() { }
-
-    public override bool Maximization => true;
-
-    public override IOperation InstrumentedApply() {
-      var solution = SymbolicExpressionTreeParameter.ActualValue;
-      var rows     = GenerateRowsToEvaluate();
-
-      var quality = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, solution,
-                              EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper,
-                              ProblemDataParameter.ActualValue, rows, ApplyLinearScalingParameter.ActualValue.Value);
-      QualityParameter.ActualValue = new DoubleValue(quality);
-      return base.InstrumentedApply();
-    }
-
-    public static double Calculate(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter,
-                                   ISymbolicExpressionTree tree, double lowerEstimationLimit,
-                                   double upperEstimationLimit, IRegressionProblemData problemData,
-                                   IEnumerable<int> rows, bool applyLinearScaling) {
-      var estimatedValues = interpreter.GetSymbolicExpressionTreeValues(tree, problemData.Dataset, rows);
-      var targetValues    = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows);
-
-      var constraints    = problemData.IntervalConstraints.EnabledConstraints;
-      var variableRanges = problemData.VariableRanges.GetReadonlyDictionary();
-
-      if (!SymbolicRegressionConstraintAnalyzer.ConstraintsSatisfied(constraints, variableRanges, tree, out double error)) return 0;
-
-      var r2 = SymbolicRegressionConstantOptimizationEvaluator.OptimizeConstants(interpreter, tree, problemData,
-                                                                                 problemData.TrainingIndices,
-                                                                                 applyLinearScaling, 10);
-      return r2;
-    }
-
-    public override double Evaluate(IExecutionContext context, ISymbolicExpressionTree tree,
-                                    IRegressionProblemData problemData, IEnumerable<int> rows) {
-      SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = context;
-      EstimationLimitsParameter.ExecutionContext                    = context;
-      ApplyLinearScalingParameter.ExecutionContext                  = context;
-
-      var r2 = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree,
-                         EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper,
-                         problemData, rows,
-                         ApplyLinearScalingParameter.ActualValue.Value);
-
-      SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = null;
-      EstimationLimitsParameter.ExecutionContext                    = null;
-      ApplyLinearScalingParameter.ExecutionContext                  = null;
-
-      return r2;
-    }
-  }
-}
Index: /branches/3076_IA_evaluators_analyzers/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionSingleObjectiveConstraintEvaluator.cs
===================================================================
--- /branches/3076_IA_evaluators_analyzers/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionSingleObjectiveConstraintEvaluator.cs	(revision 17744)
+++ /branches/3076_IA_evaluators_analyzers/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionSingleObjectiveConstraintEvaluator.cs	(revision 17744)
@@ -0,0 +1,220 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using HEAL.Attic;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Parameters;
+using HeuristicLab.Problems.DataAnalysis.Symbolic.Regression;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
+  [Item("Constraints Evaluator", "Calculates NMSE of a symbolic regression solution with respect to constraints.")]
+  [StorableType("27473973-DD8D-4375-997D-942E2280AE8E")]
+  class SymbolicRegressionSingleObjectiveConstraintEvaluator : SymbolicRegressionSingleObjectiveEvaluator {
+    #region Parameter/Properties
+
+    private const string UseConstantOptimizationParameterName = "Use Constant Optimization";
+
+    private const string ConstantOptimizationIterationsParameterName = "Constant Optimization Iterations";
+
+    private const string UseSoftConstraintsParameterName = "Use Soft Constraints Evaluation";
+
+    private const string PenaltyMultiplierParameterName = "Constraints Penalty Multiplier";
+
+    public IFixedValueParameter<BoolValue> UseConstantOptimizationParameter =>
+      (IFixedValueParameter<BoolValue>) Parameters[UseConstantOptimizationParameterName];
+
+    public IFixedValueParameter<IntValue> ConstantOptimizationIterationsParameter =>
+      (IFixedValueParameter<IntValue>) Parameters[ConstantOptimizationIterationsParameterName];
+
+    public IFixedValueParameter<BoolValue> UseSoftConstraintsParameter =>
+      (IFixedValueParameter<BoolValue>) Parameters[UseSoftConstraintsParameterName];
+
+    public IFixedValueParameter<DoubleValue> PenaltyMultiplierParameter =>
+      (IFixedValueParameter<DoubleValue>) Parameters[PenaltyMultiplierParameterName];
+
+    public bool UseConstantOptimization {
+      get => UseConstantOptimizationParameter.Value.Value;
+      set => UseConstantOptimizationParameter.Value.Value = value;
+    }
+
+    public int ConstantOptimizationIterations {
+      get => ConstantOptimizationIterationsParameter.Value.Value;
+      set => ConstantOptimizationIterationsParameter.Value.Value = value;
+    }
+
+    public bool UseSoftConstraints {
+      get => UseSoftConstraintsParameter.Value.Value;
+      set => UseSoftConstraintsParameter.Value.Value = value;
+    }
+
+    public double PenaltyMultiplier {
+      get => PenaltyMultiplierParameter.Value.Value;
+      set => PenaltyMultiplierParameter.Value.Value = value;
+    }
+
+    //Use false for maximization, because we try to minimize the NMSE
+    public override bool Maximization => false;
+
+    #endregion
+
+    #region Constructors/Cloning
+
+    [StorableConstructor]
+    protected SymbolicRegressionSingleObjectiveConstraintEvaluator(StorableConstructorFlag _) : base(_) { }
+
+    protected SymbolicRegressionSingleObjectiveConstraintEvaluator(
+      SymbolicRegressionSingleObjectiveConstraintEvaluator original, Cloner cloner) : base(original, cloner) { }
+
+    public SymbolicRegressionSingleObjectiveConstraintEvaluator() {
+      Parameters.Add(new FixedValueParameter<BoolValue>(UseConstantOptimizationParameterName,
+        "Define whether constant optimization is active or not.", new BoolValue(false)));
+      Parameters.Add(new FixedValueParameter<IntValue>(ConstantOptimizationIterationsParameterName,
+        "Define how many constant optimization steps should be performed.", new IntValue(10)));
+      Parameters.Add(new FixedValueParameter<BoolValue>(UseSoftConstraintsParameterName,
+        "Define whether the constraints are penalized by soft or hard constraints.", new BoolValue(false)));
+      Parameters.Add(new FixedValueParameter<DoubleValue>(PenaltyMultiplierParameterName,
+        "Specify how hard constraints violations should be punished", new DoubleValue(1.0)));
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      if (!Parameters.ContainsKey(UseConstantOptimizationParameterName)) {
+        Parameters.Add(new FixedValueParameter<BoolValue>(UseConstantOptimizationParameterName,
+          "Define whether constant optimization is active or not.", new BoolValue(false)));
+      }
+
+      if (!Parameters.ContainsKey(ConstantOptimizationIterationsParameterName)) {
+        Parameters.Add(new FixedValueParameter<IntValue>(ConstantOptimizationIterationsParameterName,
+          "Define how many constant optimization steps should be performed.", new IntValue(10)));
+      }
+
+      if (!Parameters.ContainsKey(UseSoftConstraintsParameterName)) {
+        Parameters.Add(new FixedValueParameter<BoolValue>(UseSoftConstraintsParameterName,
+          "Define whether the constraints are penalized by soft or hard constraints.", new BoolValue(false)));
+      }
+
+      if (!Parameters.ContainsKey(PenaltyMultiplierParameterName)) {
+        Parameters.Add(new FixedValueParameter<DoubleValue>(PenaltyMultiplierParameterName,
+          "Specify how hard constraints violations should be punished", new DoubleValue(1.0)));
+      }
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SymbolicRegressionSingleObjectiveConstraintEvaluator(this, cloner);
+    }
+
+    #endregion
+
+    public override IOperation InstrumentedApply() {
+      var rows               = GenerateRowsToEvaluate();
+      var solution           = SymbolicExpressionTreeParameter.ActualValue;
+      var problemData        = ProblemDataParameter.ActualValue;
+      var interpreter        = SymbolicDataAnalysisTreeInterpreterParameter.ActualValue;
+      var estimationLimits   = EstimationLimitsParameter.ActualValue;
+      var applyLinearScaling = ApplyLinearScalingParameter.ActualValue.Value;
+
+      if (applyLinearScaling) {
+        //Check for interval arithmetic grammar
+        //remove scaling nodes for linear scaling evaluation
+        var                    rootNode  = new ProgramRootSymbol().CreateTreeNode();
+        var                    startNode = new StartSymbol().CreateTreeNode();
+        SymbolicExpressionTree newTree   = null;
+        foreach (var node in solution.IterateNodesPrefix())
+          if (node.Symbol.Name == "Scaling") {
+            for (var i = 0; i < node.SubtreeCount; ++i) startNode.AddSubtree(node.GetSubtree(i));
+            rootNode.AddSubtree(startNode);
+            newTree = new SymbolicExpressionTree(rootNode);
+            break;
+          }
+
+        //calculate alpha and beta for scaling
+        var estimatedValues = interpreter.GetSymbolicExpressionTreeValues(newTree, problemData.Dataset, rows);
+        var targetValues    = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows);
+        OnlineLinearScalingParameterCalculator.Calculate(estimatedValues, targetValues, out var alpha, out var beta,
+          out var errorState);
+        //Set alpha and beta to the scaling nodes from ia grammar
+        foreach (var node in solution.IterateNodesPrefix())
+          if (node.Symbol.Name == "Offset") {
+            node.RemoveSubtree(1);
+            var alphaNode = new ConstantTreeNode(new Constant()) {Value = alpha};
+            node.AddSubtree(alphaNode);
+          } else if (node.Symbol.Name == "Scaling") {
+            node.RemoveSubtree(1);
+            var betaNode = new ConstantTreeNode(new Constant()) {Value = beta};
+            node.AddSubtree(betaNode);
+          }
+      }
+
+      if (UseConstantOptimization) {
+        SymbolicRegressionConstantOptimizationEvaluator.OptimizeConstants(interpreter, solution, problemData, rows,
+          false, ConstantOptimizationIterations, true,
+          estimationLimits.Lower, estimationLimits.Upper);
+      }
+
+      var quality = Calculate(interpreter, solution, estimationLimits.Lower, estimationLimits.Upper, problemData, rows, UseSoftConstraints,
+        PenaltyMultiplier);
+      QualityParameter.ActualValue = new DoubleValue(quality);
+
+      return base.InstrumentedApply();
+    }
+
+    public static double Calculate(
+      ISymbolicDataAnalysisExpressionTreeInterpreter interpreter,
+      ISymbolicExpressionTree solution, double lowerEstimationLimit,
+      double upperEstimationLimit,
+      IRegressionProblemData problemData, IEnumerable<int> rows, bool useSoftConstraints,
+      double penaltyMultiplier) {
+      var estimatedValues = interpreter.GetSymbolicExpressionTreeValues(solution, problemData.Dataset, rows);
+      var targetValues   = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows);
+      var constraints    = problemData.IntervalConstraints.EnabledConstraints;
+      var variableRanges = problemData.VariableRanges.GetReadonlyDictionary();
+
+      var boundedEstimatedValues = estimatedValues.LimitToRange(lowerEstimationLimit, upperEstimationLimit);
+      var nmse = OnlineNormalizedMeanSquaredErrorCalculator.Calculate(targetValues, boundedEstimatedValues,
+        out var errorState);
+
+      if (!SymbolicRegressionConstraintAnalyzer.ConstraintsSatisfied(constraints, variableRanges, solution, out var error)) {
+        if (useSoftConstraints) {
+          if (double.IsNaN(error) || double.IsInfinity(error)) {
+            nmse += penaltyMultiplier * 1.0;
+          } else {
+            nmse += penaltyMultiplier * error;
+          }
+
+          nmse = Math.Min(1.0, nmse);
+        } else {
+          nmse = 1.0;
+        }
+      }
+
+      if (errorState != OnlineCalculatorError.None) {
+        nmse = 1.0;
+      }
+
+      return nmse;
+    }
+
+    public override double Evaluate(
+      IExecutionContext context, ISymbolicExpressionTree tree, IRegressionProblemData problemData,
+      IEnumerable<int> rows) {
+      SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = context;
+      EstimationLimitsParameter.ExecutionContext                    = context;
+      ApplyLinearScalingParameter.ExecutionContext = context;
+
+      var nmse = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree,
+        EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper,
+        problemData, rows, UseSoftConstraints, PenaltyMultiplier);
+
+      SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = null;
+      EstimationLimitsParameter.ExecutionContext                    = null;
+      ApplyLinearScalingParameter.ExecutionContext                  = null;
+
+      return nmse;
+    }
+  }
+}
Index: anches/3076_IA_evaluators_analyzers/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionSingleObjectiveConstraintPearsonRSquaredEvaluator.cs
===================================================================
--- /branches/3076_IA_evaluators_analyzers/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionSingleObjectiveConstraintPearsonRSquaredEvaluator.cs	(revision 17743)
+++ 	(revision )
@@ -1,81 +1,0 @@
-﻿using System.Collections.Generic;
-using HEAL.Attic;
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Data;
-using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
-
-namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Regression {
-  [Item("Pearson R² Constraint Evaluator",
-    "Calculates the square of the pearson correlation coefficient (also known as coefficient of determination) of a symbolic regression solution.")]
-  [StorableType("D61462E4-2032-4790-B63D-5E6512987F64")]
-  public class SymbolicRegressionSingleObjectiveConstraintPearsonRSquaredEvaluator : SymbolicRegressionSingleObjectiveEvaluator {
-    [StorableConstructor]
-    protected SymbolicRegressionSingleObjectiveConstraintPearsonRSquaredEvaluator(StorableConstructorFlag _) :
-      base(_) { }
-
-    protected SymbolicRegressionSingleObjectiveConstraintPearsonRSquaredEvaluator(
-      SymbolicRegressionSingleObjectiveConstraintPearsonRSquaredEvaluator original, Cloner cloner)
-      : base(original, cloner) { }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new SymbolicRegressionSingleObjectiveConstraintPearsonRSquaredEvaluator(this, cloner);
-    }
-
-    public SymbolicRegressionSingleObjectiveConstraintPearsonRSquaredEvaluator() { }
-
-    public override bool Maximization => true;
-
-    public override IOperation InstrumentedApply() {
-      var solution = SymbolicExpressionTreeParameter.ActualValue;
-      var rows     = GenerateRowsToEvaluate();
-
-      var quality = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, solution,
-                              EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper,
-                              ProblemDataParameter.ActualValue, rows, ApplyLinearScalingParameter.ActualValue.Value);
-      QualityParameter.ActualValue = new DoubleValue(quality);
-      return base.InstrumentedApply();
-    }
-
-    public static double Calculate(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter,
-                                   ISymbolicExpressionTree solution, double lowerEstimationLimit,
-                                   double upperEstimationLimit, IRegressionProblemData problemData,
-                                   IEnumerable<int> rows, bool applyLinearScaling) {
-      var estimatedValues = interpreter.GetSymbolicExpressionTreeValues(solution, problemData.Dataset, rows);
-      var targetValues    = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows);
-      var errorState      = OnlineCalculatorError.None;
-      
-      var constraints    = problemData.IntervalConstraints.EnabledConstraints;
-      var variableRanges = problemData.VariableRanges.GetReadonlyDictionary();
-      var tree           = solution;
-
-      if (!SymbolicRegressionConstraintAnalyzer.ConstraintsSatisfied(constraints, variableRanges, tree, out double error)) return 0;
-
-      var r2 = SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.Calculate(interpreter, solution,
-                                                                                   lowerEstimationLimit,
-                                                                                   upperEstimationLimit, problemData,
-                                                                                   rows, applyLinearScaling);
-
-      return r2;
-    }
-
-
-    public override double Evaluate(IExecutionContext context, ISymbolicExpressionTree tree,
-                                    IRegressionProblemData problemData, IEnumerable<int> rows) {
-      SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = context;
-      EstimationLimitsParameter.ExecutionContext                    = context;
-      ApplyLinearScalingParameter.ExecutionContext                  = context;
-
-      var r2 = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree,
-                         EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper,
-                         problemData, rows,
-                         ApplyLinearScalingParameter.ActualValue.Value);
-
-      SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = null;
-      EstimationLimitsParameter.ExecutionContext                    = null;
-      ApplyLinearScalingParameter.ExecutionContext                  = null;
-
-      return r2;
-    }
-  }
-}
