Changeset 17995


Ignore:
Timestamp:
06/22/21 18:28:36 (13 months ago)
Author:
dpiringe
Message:

#3119

  • added additional parameters to enable different evaluation options
  • added additive restrictions
  • added additional implementations for dynamic restrictions:
    • dynamic intervalls
    • exponatial smoothing
    • rising multiplier
  • adapted IntervalUtil to get model bounds and refactored some sections
  • adapted ShapeConstraintsParser for added features
  • added a ResultCollection in SymbolicRegressionSolution for shape constraint violations
Location:
branches/3119_AdditionalShapeConstraintFeatures
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • branches/3119_AdditionalShapeConstraintFeatures/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression-3.4.csproj

    r17931 r17995  
    131131    <Compile Include="SingleObjective\Evaluators\SymbolicRegressionMeanRelativeErrorEvaluator.cs" />
    132132    <Compile Include="SingleObjective\SymbolicRegressionSolutionsAnalyzer.cs" />
     133    <Compile Include="SymbolicRegressionMetaModelAnalyzer.cs" />
    133134    <Compile Include="SymbolicRegressionPhenotypicDiversityAnalyzer.cs" />
    134135    <Compile Include="SymbolicRegressionPruningAnalyzer.cs" />
     
    158159    <Compile Include="SingleObjective\Evaluators\SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.cs" />
    159160    <Compile Include="SymbolicRegressionPruningOperator.cs" />
     161    <Compile Include="SymbolicRegressionSingleObjectiveMetaModelAnalyzer.cs" />
    160162    <Compile Include="SymbolicRegressionSolution.cs" />
    161163    <Compile Include="SymbolicRegressionSolutionImpactValuesCalculator.cs" />
  • branches/3119_AdditionalShapeConstraintFeatures/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/Plugin.cs.frame

    r17931 r17995  
    3737  [PluginDependency("HeuristicLab.Operators", "3.3")]
    3838  [PluginDependency("HeuristicLab.Optimization", "3.3")]
     39  [PluginDependency("HeuristicLab.Optimization.Operators", "3.3")]
    3940  [PluginDependency("HeuristicLab.Parameters", "3.3")]
    4041  [PluginDependency("HeuristicLab.Attic", "1.0")]
  • branches/3119_AdditionalShapeConstraintFeatures/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/NMSEConstraintsEvaluator.cs

    r17914 r17995  
    2424using System.Linq;
    2525using HEAL.Attic;
     26using HeuristicLab.Analysis;
    2627using HeuristicLab.Common;
    2728using HeuristicLab.Core;
    2829using HeuristicLab.Data;
    2930using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
     31using HeuristicLab.Optimization;
     32using HeuristicLab.Optimization.Operators;
    3033using HeuristicLab.Parameters;
    3134using HeuristicLab.Problems.DataAnalysis.Symbolic.Regression;
     
    3942    private const string OptimizeParametersParameterName = "OptimizeParameters";
    4043    private const string ParameterOptimizationIterationsParameterName = "ParameterOptimizationIterations";
     44    private const string UseConstraintsParameterName = "UseConstraintsEvaluation";
    4145    private const string UseSoftConstraintsParameterName = "UseSoftConstraintsEvaluation";
    4246    private const string BoundsEstimatorParameterName = "BoundsEstimator";
    4347    private const string PenaltyFactorParameterName = "PenaltyFactor";
     48    private const string GenerationOfConvergenceParameterName = "Generation of Convergence";
     49    private const string AlphaParameterName = "Alpha";
     50    private const string ResultCollectionParameterName = "Results";
     51    private const string GenerationsEntry = "Generations";
     52    private const string LPValueParameterName = "Low Pass Value";
     53    private const string UseDynamicPenaltyImpl1ParameterName = "UseDynamicPenaltyImpl1";
     54    private const string UseDynamicPenaltyImpl2ParameterName = "UseDynamicPenaltyImpl2";
     55    private const string UseDynamicPenaltyImpl3ParameterName = "UseDynamicPenaltyImpl3";
     56    private const string UseAdditivePenaltyParameterName = "UseAdditivePenalty";
     57    private const string RisingPenaltyParameterName = "RisingPenalty";
     58    private const string StepSizeParameterName = "Step Size";
     59    private const string MaximumStepsParameterName = "Maximum Steps";
     60    private const string StartpenaltyParameterName = "Start penalty";
    4461
    4562
     
    5067      (IFixedValueParameter<IntValue>)Parameters[ParameterOptimizationIterationsParameterName];
    5168
     69    public IFixedValueParameter<BoolValue> UseConstraintsParameter =>
     70      (IFixedValueParameter<BoolValue>)Parameters[UseConstraintsParameterName];
     71
    5272    public IFixedValueParameter<BoolValue> UseSoftConstraintsParameter =>
    5373      (IFixedValueParameter<BoolValue>)Parameters[UseSoftConstraintsParameterName];
     
    5575    public IValueParameter<IBoundsEstimator> BoundsEstimatorParameter =>
    5676      (IValueParameter<IBoundsEstimator>)Parameters[BoundsEstimatorParameterName];
     77
    5778    public IFixedValueParameter<DoubleValue> PenaltyFactorParameter =>
    5879      (IFixedValueParameter<DoubleValue>)Parameters[PenaltyFactorParameterName];
     80
     81    public IFixedValueParameter<IntValue> GenerationOfConvergenceParameter =>
     82      (IFixedValueParameter<IntValue>)Parameters[GenerationOfConvergenceParameterName];
     83
     84    public IFixedValueParameter<DoubleValue> AlphaParameter =>
     85      (IFixedValueParameter<DoubleValue>)Parameters[AlphaParameterName];
     86
     87    public ILookupParameter<ResultCollection> ResultCollectionParameter =>
     88      (ILookupParameter<ResultCollection>)Parameters[ResultCollectionParameterName];
     89
     90    public IResultParameter<DataTable> LPValueParameter {
     91      get {
     92        if (Parameters.TryGetValue(LPValueParameterName, out IParameter p))
     93          return (IResultParameter<DataTable>)p;
     94        return null;
     95      }
     96    }
     97
     98    public IFixedValueParameter<BoolValue> UseDynamicPenaltyImpl1Parameter =>
     99      (IFixedValueParameter<BoolValue>)Parameters[UseDynamicPenaltyImpl1ParameterName];
     100
     101    public IFixedValueParameter<BoolValue> UseDynamicPenaltyImpl2Parameter =>
     102      (IFixedValueParameter<BoolValue>)Parameters[UseDynamicPenaltyImpl2ParameterName];
     103
     104    public IFixedValueParameter<BoolValue> UseDynamicPenaltyImpl3Parameter =>
     105      (IFixedValueParameter<BoolValue>)Parameters[UseDynamicPenaltyImpl3ParameterName];
     106
     107    public IFixedValueParameter<BoolValue> UseAdditivePenaltyParameter =>
     108      (IFixedValueParameter<BoolValue>)Parameters[UseAdditivePenaltyParameterName];
     109
     110    public IFixedValueParameter<IntValue> StepSizeParameter =>
     111      (IFixedValueParameter<IntValue>)Parameters[StepSizeParameterName];
     112
     113    public IFixedValueParameter<IntValue> MaximumStepsParameter =>
     114      (IFixedValueParameter<IntValue>)Parameters[MaximumStepsParameterName];
     115
     116    public IResultParameter<DataTable> RisingPenaltyParameter {
     117      get {
     118        if (Parameters.TryGetValue(RisingPenaltyParameterName, out IParameter p))
     119          return (IResultParameter<DataTable>)p;
     120        return null;
     121      }
     122    }
     123
     124    public IFixedValueParameter<DoubleValue> StartpenaltyParameter =>
     125      (IFixedValueParameter<DoubleValue>)Parameters[StartpenaltyParameterName];
    59126
    60127    public bool OptimizeParameters {
     
    68135    }
    69136
     137    public bool UseConstraints {
     138      get => UseConstraintsParameter.Value.Value;
     139      set => UseConstraintsParameter.Value.Value = value;
     140    }
     141
    70142    public bool UseSoftConstraints {
    71143      get => UseSoftConstraintsParameter.Value.Value;
     
    78150    }
    79151
    80     public double PenalityFactor {
     152    public double PenaltyFactor {
    81153      get => PenaltyFactorParameter.Value.Value;
    82154      set => PenaltyFactorParameter.Value.Value = value;
    83155    }
    84156
     157    public int GenerationOfConvergence {
     158      get => GenerationOfConvergenceParameter.Value.Value;
     159      set => GenerationOfConvergenceParameter.Value.Value = value;
     160    }
     161
     162    public double Alpha {
     163      get => AlphaParameter.Value.Value;
     164      set => AlphaParameter.Value.Value = value;
     165    }
     166
     167    public ResultCollection ResultCollection =>
     168      ResultCollectionParameter.ActualValue;
     169
     170    private IntValue Generations {
     171      get {
     172        IResult result;
     173        ResultCollection.TryGetValue(GenerationsEntry, out result);
     174        if (result == null) return new IntValue(0);
     175        return result.Value == null ? new IntValue(0) : (IntValue)result.Value;
     176      }
     177    }
    85178
    86179    public override bool Maximization => false; // NMSE is minimized
     
    99192      Parameters.Add(new FixedValueParameter<BoolValue>(OptimizeParametersParameterName,
    100193        "Define whether optimization of numeric parameters is active or not (default: false).", new BoolValue(false)));
     194      Parameters.Add(new FixedValueParameter<BoolValue>(UseConstraintsParameterName,
     195        "Define whether evaluation of constraints is active or not (default: true).", new BoolValue(true)));
    101196      Parameters.Add(new FixedValueParameter<IntValue>(ParameterOptimizationIterationsParameterName,
    102197        "Define how many parameter optimization steps should be performed (default: 10).", new IntValue(10)));
     
    107202      Parameters.Add(new FixedValueParameter<DoubleValue>(PenaltyFactorParameterName,
    108203        "Punishment factor for constraint violations for soft constraint handling (fitness = NMSE + penaltyFactor * avg(violations)) (default: 1.0)", new DoubleValue(1.0)));
     204      Parameters.Add(new FixedValueParameter<IntValue>(GenerationOfConvergenceParameterName, "", new IntValue(100)));
     205      Parameters.Add(new FixedValueParameter<DoubleValue>(AlphaParameterName, "", new DoubleValue(0.9)));
     206      Parameters.Add(new LookupParameter<ResultCollection>(ResultCollectionParameterName, "The result collection to store the analysis results."));
     207
     208      Parameters.Add(new FixedValueParameter<BoolValue>(UseDynamicPenaltyImpl1ParameterName, "", new BoolValue(false)));
     209      Parameters.Add(new FixedValueParameter<BoolValue>(UseDynamicPenaltyImpl2ParameterName, "", new BoolValue(false)));
     210      Parameters.Add(new FixedValueParameter<BoolValue>(UseDynamicPenaltyImpl3ParameterName, "", new BoolValue(false)));
     211      Parameters.Add(new FixedValueParameter<BoolValue>(UseAdditivePenaltyParameterName, "", new BoolValue(false)));
     212     
     213
     214      Parameters.Add(new FixedValueParameter<IntValue>(StepSizeParameterName,
     215        "Defines the step size for the increasing penalty multiplier.", new IntValue(1)));
     216      Parameters.Add(new FixedValueParameter<IntValue>(MaximumStepsParameterName,
     217        "Defines maximum steps for the increasing penalty multiplier.", new IntValue(1000)));
     218      Parameters.Add(new FixedValueParameter<DoubleValue>(StartpenaltyParameterName,
     219        "The start value for the penalty multiplier.", new DoubleValue(0.5)));
     220
     221      /*
     222      Parameters.Add(new ResultParameter<DataTable>(RisingPenaltyParameterName,
     223        "Shows the behavior of the penalty multiplier."));
     224      RisingPenaltyParameter.DefaultValue = new DataTable(RisingPenaltyParameterName) {
     225        VisualProperties = {
     226          XAxisTitle = "Generations",
     227          YAxisTitle = "penalty Multiplier"
     228        }
     229      };
     230
     231
     232      Parameters.Add(new ResultParameter<DataTable>(LPValueParameterName,
     233        "Low Pass Value"));
     234      LPValueParameter.DefaultValue = new DataTable(LPValueParameterName) {
     235        VisualProperties = {
     236          XAxisTitle = "Generations",
     237          YAxisTitle = "Value"
     238        }
     239      };*/
    109240    }
    110241
     
    125256      var estimationLimits = EstimationLimitsParameter.ActualValue;
    126257      var applyLinearScaling = ApplyLinearScalingParameter.ActualValue.Value;
    127 
     258     
    128259      if (OptimizeParameters) {
    129260        SymbolicRegressionConstantOptimizationEvaluator.OptimizeConstants(interpreter, tree, problemData, rows,
     
    165296
    166297      var quality = Calculate(interpreter, tree, estimationLimits.Lower, estimationLimits.Upper, problemData, rows,
    167         BoundsEstimator, UseSoftConstraints, PenalityFactor);
     298        BoundsEstimator, UseConstraints, UseSoftConstraints,
     299        UseDynamicPenaltyImpl1Parameter.Value.Value, UseDynamicPenaltyImpl2Parameter.Value.Value,
     300        UseDynamicPenaltyImpl3Parameter.Value.Value, UseAdditivePenaltyParameter.Value.Value,
     301        PenaltyFactor,
     302        StepSizeParameter.Value.Value, StartpenaltyParameter.Value.Value, MaximumStepsParameter.Value.Value,
     303        RisingPenaltyParameter?.ActualValue,
     304        Generations.Value, GenerationOfConvergence, Alpha,
     305        LPValueParameter);
    168306      QualityParameter.ActualValue = new DoubleValue(quality);
    169307
    170308      return base.InstrumentedApply();
    171309    }
     310
     311    public override void InitializeState() {
     312      oldValue = 0.0;
     313      actualValue = 0.0;
     314      oldGeneration = 0;
     315      base.InitializeState();
     316    }
     317
     318    // bei mehrmaligen ausführungen bleibt der state!
     319    private static int oldGeneration = 0;
     320    private static double oldValue = 0.0;
     321    private static double actualValue = 0.0;
    172322
    173323    public static double Calculate(
     
    177327      IRegressionProblemData problemData, IEnumerable<int> rows,
    178328      IBoundsEstimator estimator,
    179       bool useSoftConstraints = false, double penaltyFactor = 1.0) {
     329      bool useConstraints, bool useSoftConstraints = false,
     330      bool useDynamicConstraints1 = false, bool useDynamicConstraints2 = false, bool useDynamicConstraints3 = false,
     331      bool useAdditivePenalty = false,
     332      double penaltyFactor = 1.0,
     333      int stepSize = 1, double startpenalty = 0.5, int maximumSteps = 1000, DataTable penaltyDataTable = null,
     334      int generation = 0, int generationOfConvergence = 100, double alpha = 0.9,
     335      IResultParameter<DataTable> lpValueParameter = null) {
     336
     337      double risingPenalty = 1.0;
     338      if (useDynamicConstraints1) {
     339        risingPenalty = LinearDiscreteDoubleValueModifier.Apply(0, startpenalty, 1.0,
     340          (int)(generation / stepSize) * stepSize, 0, maximumSteps);
     341      }
     342
     343      if (oldGeneration != generation) {
     344        oldGeneration = generation;
     345
     346        if(lpValueParameter != null) {
     347          var LPValueParameterDataTable = lpValueParameter.ActualValue;
     348          if (LPValueParameterDataTable.Rows.Count == 0)
     349            LPValueParameterDataTable.Rows.Add(new DataRow(LPValueParameterName));
     350
     351          LPValueParameterDataTable.Rows[LPValueParameterName]
     352            .Values
     353            .Add(oldValue);
     354        }
     355       
     356        if (penaltyDataTable != null && useDynamicConstraints1) {
     357          if (penaltyDataTable.Rows.Count == 0)
     358            penaltyDataTable.Rows.Add(new DataRow("LinearDiscreteDoubleValueModifier"));
     359          penaltyDataTable.Rows["LinearDiscreteDoubleValueModifier"].Values.Add(risingPenalty);
     360        }
     361
     362        oldValue = actualValue;
     363      }
    180364
    181365      var estimatedValues = interpreter.GetSymbolicExpressionTreeValues(tree, problemData.Dataset, rows);
     
    189373
    190374      if (errorState != OnlineCalculatorError.None) {
    191         return 1.0;
     375        actualValue = alpha * 1.0 + (1.0 - alpha) * actualValue;
     376        return 10000.0;
     377      }
     378
     379      if (!useConstraints)
     380        return nmse;
     381
     382
     383      if(useDynamicConstraints2) {
     384        foreach(var c in constraints) {
     385          if(!double.IsNegativeInfinity(c.DynInterval.LowerBound) && !double.IsPositiveInfinity(c.DynInterval.UpperBound)) {
     386            int step = (int)(generation / stepSize) * stepSize;
     387            var lb = LinearDiscreteDoubleValueModifier.Apply(0, c.DynInterval.LowerBound, c.TargetInterval.LowerBound, step, 0, maximumSteps);
     388            var ub = LinearDiscreteDoubleValueModifier.Apply(0, c.DynInterval.UpperBound, c.TargetInterval.UpperBound, step, 0, maximumSteps);
     389            c.Interval = new Interval(lb, ub);
     390          }
     391        }
     392      } else {
     393        foreach (var c in constraints) {
     394          c.Interval = new Interval(c.TargetInterval.LowerBound, c.TargetInterval.UpperBound);
     395        }
    192396      }
    193397
    194398      var constraintViolations = IntervalUtil.GetConstraintViolations(constraints, estimator, intervalCollection, tree);
     399      var constraintBounds = IntervalUtil.GetModelBounds(constraints, estimator, intervalCollection, tree);
    195400
    196401      if (constraintViolations.Any(x => double.IsNaN(x) || double.IsInfinity(x))) {
    197         return 1.0;
    198       }
     402        actualValue = alpha * 1.0 + (1.0 - alpha) * actualValue;
     403        return 10000.0;
     404      }
     405
     406
     407      /*
     408      if(constraintViolations.Any(x => x > 0.0)) {
     409        actualValue = alpha * 1.0 + (1.0 - alpha) * actualValue;
     410      } else {
     411        actualValue *= (1.0 - alpha);
     412      }*/
    199413
    200414      if (useSoftConstraints) {
     
    202416          throw new ArgumentException("The parameter has to be greater or equal 0.0!", nameof(penaltyFactor));
    203417
     418
     419        var errors = constraints
     420          .Zip(constraintBounds, CalcSoftConstraintError);
     421
     422        var weightedViolationSum = constraints
     423          .Zip(errors, (c, e) => c.Weight * e)
     424          .Average();
     425
     426        /*
    204427        var weightedViolationSum = constraints
    205428          .Zip(constraintViolations, (c, v) => c.Weight * v)
    206429          .Average();
    207 
    208         return Math.Min(nmse, 1.0) + penaltyFactor * weightedViolationSum;
     430        */
     431
     432        actualValue = alpha * errors.Average() + (1.0 - alpha) * actualValue;
     433
     434        var violation = (weightedViolationSum * penaltyFactor);
     435        if (useDynamicConstraints1)
     436          violation *= risingPenalty;
     437
     438
     439        if (useDynamicConstraints3)
     440          violation *= oldValue;
     441
     442        if (useAdditivePenalty)
     443          nmse += violation;
     444        else
     445          nmse += nmse * violation;
     446
     447
     448        return nmse;
     449          //Math.Min(nmse, 1.0) +
     450          //(Math.Min(nmse, 1.0) *
     451          //(//(penaltyFactor * oldValue) *
     452          /*Math.Min(penaltyFactor, penaltyFactor * ((generation + 1) / generationOfConvergence)) * */ /* penaltyFactor rises over time */
     453          //penaltyFactor * weightedViolationSum);
    209454      } else if (constraintViolations.Any(x => x > 0.0)) {
    210455        return 1.0;
    211       }
     456      } // globale constraints -> wenn diese verletzt werden -> nmse = 1.0 ????
     457        // analyzer -> avg. quality von lösung die nix verletzen
     458
    212459
    213460      return nmse;
     461    }
     462
     463    private static double CalcSoftConstraintError(ShapeConstraint constraint, Interval bounds) {
     464      if (!constraint.Interval.Contains(bounds)) {
     465
     466        // get the absolute threshold bounds
     467        var thresholdLb = Math.Abs(constraint.Threshold.LowerBound);
     468        var thresholdUb = Math.Abs(constraint.Threshold.UpperBound);
     469
     470        // calc the absolute bound errors
     471        var errorLb = 0.0;//Math.Abs(Math.Abs(b.LowerBound) - Math.Abs(c.Interval.LowerBound));
     472        var errorUb = 0.0;//Math.Abs(Math.Abs(b.UpperBound) - Math.Abs(c.Interval.UpperBound));
     473
     474        if (!constraint.Interval.Contains(bounds.LowerBound)) {
     475          errorLb = Math.Abs(bounds.LowerBound - constraint.Interval.LowerBound); // immer einfach 0 als "Mitte"?
     476        }
     477
     478        if (!constraint.Interval.Contains(bounds.UpperBound)) {
     479          errorUb = Math.Abs(bounds.UpperBound - constraint.Interval.UpperBound);
     480        }
     481
     482        double relativeLb;
     483        if (double.IsInfinity(thresholdLb))
     484          relativeLb = 0.0;
     485        if (thresholdLb > 0.0) {
     486          relativeLb = errorLb / thresholdLb;
     487          relativeLb = double.IsNaN(relativeLb) ? 1.0 : Math.Min(relativeLb, 1.0);
     488        } else
     489          relativeLb = 1.0;
     490
     491        double relativeUb;
     492        if (double.IsInfinity(thresholdUb))
     493          relativeUb = 0.0;
     494        else if (thresholdUb > 0.0) {
     495          relativeUb = errorUb / thresholdUb;
     496          relativeUb = double.IsNaN(relativeUb) ? 1.0 : Math.Min(relativeUb, 1.0);
     497        } else
     498          relativeUb = 1.0;
     499
     500        var error = (relativeLb + relativeUb) / 2.0;
     501        //actualValue = alpha * error + (1.0 - alpha) * actualValue;
     502        return error; //* constraint.Weight;
     503      }
     504      //actualValue *= (1.0 - alpha);
     505      return 0.0;
    214506    }
    215507
     
    223515      var nmse = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree,
    224516        EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper,
    225         problemData, rows, BoundsEstimator, UseSoftConstraints, PenalityFactor);
     517        problemData, rows, BoundsEstimator, UseConstraints, UseSoftConstraints,
     518        UseDynamicPenaltyImpl1Parameter.Value.Value, UseDynamicPenaltyImpl2Parameter.Value.Value,
     519        UseDynamicPenaltyImpl3Parameter.Value.Value, UseAdditivePenaltyParameter.Value.Value,
     520        PenaltyFactor,
     521        StepSizeParameter.Value.Value, StartpenaltyParameter.Value.Value, MaximumStepsParameter.Value.Value);
    226522
    227523      SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = null;
  • branches/3119_AdditionalShapeConstraintFeatures/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SymbolicRegressionSolution.cs

    r17911 r17995  
    3838    private const string ModelDepthResultName = "Model Depth";
    3939
     40    private const string ConstraintViolationsResultsResultName = "Constraint Violations Results";
     41
    4042    private const string EstimationLimitsResultsResultName = "Estimation Limits Results";
    4143    private const string EstimationLimitsResultName = "Estimation Limits";
     
    6466      get { return ((IntValue)this[ModelDepthResultName].Value).Value; }
    6567      private set { ((IntValue)this[ModelDepthResultName].Value).Value = value; }
     68    }
     69
     70    public ResultCollection ConstraintViolationsResults {
     71      get { return (ResultCollection)this[ConstraintViolationsResultsResultName].Value; }
    6672    }
    6773
     
    136142      estimationLimitResults.Add(new Result(TestNaNEvaluationsResultName, "", new IntValue()));
    137143      Add(new Result(EstimationLimitsResultsResultName, "Results concerning the estimation limits of symbolic regression solution", estimationLimitResults));
     144
     145
     146      ResultCollection constraintViolationResults = new ResultCollection();
     147      constraintViolationResults.Add(new Result("Violations", "Count of constraint violations", new IntValue()));
     148      foreach (var constraint in problemData.ShapeConstraints.EnabledConstraints)
     149        constraintViolationResults.Add(new Result(constraint.ToString(), "", new DoubleValue()));
     150      Add(new Result(ConstraintViolationsResultsResultName, "Results concerning the constraint violations of symbolic regression solution", constraintViolationResults));
    138151
    139152      if (IntervalInterpreter.IsCompatible(Model.SymbolicExpressionTree))
     
    159172        estimationLimitResults.Add(new Result(TestNaNEvaluationsResultName, "", new IntValue()));
    160173        Add(new Result(EstimationLimitsResultsResultName, "Results concerning the estimation limits of symbolic regression solution", estimationLimitResults));
     174
    161175        CalculateResults();
    162176      }
     
    178192      ModelLength = Model.SymbolicExpressionTree.Length;
    179193      ModelDepth = Model.SymbolicExpressionTree.Depth;
     194
     195      var constraints = ProblemData.ShapeConstraints.EnabledConstraints;
     196      var estimator = new IntervalArithBoundsEstimator();
     197      int violationCounter = 0;
     198      foreach (var constraint in constraints) {
     199        constraint.Interval = new Interval(constraint.TargetInterval.LowerBound, constraint.TargetInterval.UpperBound);
     200        var v = IntervalUtil.GetConstraintViolation(constraint, estimator, ProblemData.VariableRanges, Model.SymbolicExpressionTree);
     201        ((DoubleValue)ConstraintViolationsResults[constraint.ToString()].Value).Value = v;
     202        if(double.IsNaN(v) || double.IsInfinity(v) || v > 0) {
     203          violationCounter++;
     204        }
     205      }
     206      ((IntValue)ConstraintViolationsResults["Violations"].Value).Value = violationCounter;
     207
     208
     209      /*
     210      if(constraints.Count() > 0)
     211        ConstraintViolationsResults =
     212          IntervalUtil.GetConstraintViolations(
     213            constraints,
     214            new IntervalArithBoundsEstimator(),
     215            ProblemData.VariableRanges,
     216            Model.SymbolicExpressionTree)
     217          .Where(x => x > 0.0).Count();
     218      */
    180219
    181220      EstimationLimits.Lower = Model.LowerEstimationLimit;
  • branches/3119_AdditionalShapeConstraintFeatures/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/IntervalUtil.cs

    r17906 r17995  
    2828namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
    2929  public static class IntervalUtil {
     30    public static IEnumerable<Interval> GetModelBounds(
     31      IEnumerable<ShapeConstraint> constraints, IBoundsEstimator estimator, IntervalCollection intervalCollection,
     32      ISymbolicExpressionTree solution) {
     33      return constraints.Select(constraint => GetModelBound(constraint, estimator, intervalCollection, solution)).ToList();
     34    }
     35
     36    public static Interval GetModelBound(
     37      ShapeConstraint constraint, IBoundsEstimator estimator, IntervalCollection variableRanges,
     38      ISymbolicExpressionTree tree) {
     39      var regionRanges = GetRegionRanges(constraint, variableRanges);
     40      tree = DeriveTree(tree, constraint, estimator);
     41      return estimator.GetModelBound(tree, regionRanges);
     42    }
     43
    3044    public static IEnumerable<double> GetConstraintViolations(
    3145      IEnumerable<ShapeConstraint> constraints, IBoundsEstimator estimator, IntervalCollection intervalCollection,
     
    3751      ShapeConstraint constraint, IBoundsEstimator estimator, IntervalCollection variableRanges,
    3852      ISymbolicExpressionTree tree) {
     53
     54      var regionRanges = GetRegionRanges(constraint, variableRanges);
     55      tree = DeriveTree(tree, constraint, estimator);
     56      return estimator.GetConstraintViolation(tree, regionRanges, constraint);
     57      /*
     58      if (!constraint.IsDerivative) {
     59        return estimator.GetConstraintViolation(tree, regionRanges, constraint);
     60      } else {
     61        for (var i = 0; i < constraint.NumberOfDerivations; ++i) {
     62          if (!estimator.IsCompatible(tree) || !DerivativeCalculator.IsCompatible(tree)) {
     63            throw new ArgumentException("The tree contains an unsupported symbol.");
     64          }
     65
     66          tree = DerivativeCalculator.Derive(tree, constraint.Variable);
     67        }
     68
     69        return estimator.GetConstraintViolation(tree, regionRanges, constraint);
     70      }
     71      */
     72    }
     73
     74    private static ISymbolicExpressionTree DeriveTree(ISymbolicExpressionTree tree, ShapeConstraint constraint, IBoundsEstimator estimator) {
     75      if (constraint.IsDerivative) {
     76        for (var i = 0; i < constraint.NumberOfDerivations; ++i) {
     77          if (!estimator.IsCompatible(tree) || !DerivativeCalculator.IsCompatible(tree))
     78            throw new ArgumentException("The tree contains an unsupported symbol.");
     79          tree = DerivativeCalculator.Derive(tree, constraint.Variable);
     80        }
     81      }
     82      return tree;
     83    }
     84
     85    private static IntervalCollection GetRegionRanges(ShapeConstraint constraint, IntervalCollection variableRanges) {
    3986      var varRanges = variableRanges.GetReadonlyDictionary();
    4087
     
    55102      }
    56103
    57       if (!constraint.IsDerivative) {
    58         return estimator.GetConstraintViolation(tree, regionRanges, constraint);
    59       } else {
    60         for (var i = 0; i < constraint.NumberOfDerivations; ++i) {
    61           if (!estimator.IsCompatible(tree) || !DerivativeCalculator.IsCompatible(tree)) {
    62             throw new ArgumentException("The tree contains an unsupported symbol.");
    63           }
    64 
    65           tree = DerivativeCalculator.Derive(tree, constraint.Variable);
    66         }
    67 
    68         return estimator.GetConstraintViolation(tree, regionRanges, constraint);
    69       }
     104      return regionRanges;
    70105    }
    71106  }
  • branches/3119_AdditionalShapeConstraintFeatures/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Interval/ShapeConstraint.cs

    r17946 r17995  
    107107
    108108    [Storable]
    109     private Interval threshold;
     109    private Interval threshold = new Interval(0, 0);
    110110    public Interval Threshold {
    111111      get => threshold;
     
    114114          return;
    115115        threshold = value;
     116        OnToStringChanged();
     117        OnChanged();
     118      }
     119    }
     120
     121
     122    [Storable]
     123    private Interval targetInterval;
     124    public Interval TargetInterval {
     125      get => targetInterval;
     126      set {
     127        if (targetInterval == value)
     128          return;
     129        targetInterval = value;
     130        OnToStringChanged();
     131        OnChanged();
     132      }
     133    }
     134
     135    [Storable]
     136    private Interval dynInterval = new Interval(double.NegativeInfinity, double.PositiveInfinity);
     137    public Interval DynInterval {
     138      get => dynInterval;
     139      set {
     140        if (dynInterval == value)
     141          return;
     142        dynInterval = value;
    116143        OnToStringChanged();
    117144        OnChanged();
     
    125152    private void AfterDeserialization() {
    126153      if (regions != null) regions.Changed += regions_Changed;
     154      if (TargetInterval == null)
     155        TargetInterval = new Interval(interval.LowerBound, interval.UpperBound);
    127156    }
    128157
    129158    // without derivation
    130     public ShapeConstraint(Interval interval, double weight, Interval threshold)
     159    public ShapeConstraint(Interval interval, double weight, Interval threshold, Interval dynInterval)
    131160      : this(string.Empty, 0,
    132          interval, new IntervalCollection(), weight, threshold) { }
    133 
    134     public ShapeConstraint(Interval interval, IntervalCollection regions, double weight, Interval threshold)
     161         interval, new IntervalCollection(), weight, threshold, dynInterval) { }
     162
     163    public ShapeConstraint(Interval interval, IntervalCollection regions, double weight, Interval threshold, Interval dynInterval)
    135164      : this(string.Empty, 0,
    136          interval, regions, weight, threshold) { }
     165         interval, regions, weight, threshold, dynInterval) { }
    137166
    138167    public ShapeConstraint(string variable, int numberOfDerivations,
    139                               Interval interval, double weight, Interval threshold)
     168                              Interval interval, double weight, Interval threshold, Interval dynInterval)
    140169      : this(variable, numberOfDerivations,
    141              interval, new IntervalCollection(), weight, threshold) { }
     170             interval, new IntervalCollection(), weight, threshold, dynInterval) { }
    142171
    143172    public ShapeConstraint(string variable, int numberOfDerivations,
    144                               Interval interval, IntervalCollection regions, double weight, Interval threshold) {
     173                              Interval interval, IntervalCollection regions, double weight, Interval threshold, Interval dynInterval) {
    145174      Variable = variable;
    146175      NumberOfDerivations = numberOfDerivations;
     
    149178      Weight = weight;
    150179      Threshold = threshold;
     180      DynInterval = dynInterval;
     181      TargetInterval = new Interval(interval.LowerBound, interval.UpperBound);
    151182    }
    152183
     
    162193      Regions = cloner.Clone(original.Regions);
    163194      Weight = original.weight;
    164     }
    165 
     195      Threshold = original.Threshold;
     196      DynInterval = original.DynInterval;
     197      TargetInterval = original.TargetInterval;
     198    }
    166199
    167200    public event EventHandler Changed;
     
    188221      string write(double val) => double.IsPositiveInfinity(val) ? "inf." : double.IsNegativeInfinity(val) ? "-inf." : $"{val}";
    189222      if (!IsDerivative) {
    190         expression = string.Format($"f in [{write(Interval.LowerBound)} .. {write(Interval.UpperBound)}]");
     223        expression = string.Format($"f in [{write(TargetInterval.LowerBound)} .. {write(TargetInterval.UpperBound)}]");
    191224      } else {
    192225        var derivationString = string.Empty;
     
    199232            derivationString = "³"; break;
    200233        }
    201         expression = string.Format($"∂{derivationString}f/∂{Variable}{derivationString} in [{write(Interval.LowerBound)} .. {write(Interval.UpperBound)}]");
     234        expression = string.Format($"∂{derivationString}f/∂{Variable}{derivationString} in [{write(TargetInterval.LowerBound)} .. {write(TargetInterval.UpperBound)}]");
    202235      }
    203236
     
    209242        expression += $" weight: {weight}";
    210243      }
     244
    211245      if (!double.IsNegativeInfinity(Threshold.LowerBound) || !double.IsPositiveInfinity(Threshold.UpperBound))
    212         expression += $" threshold: [{write(Threshold.LowerBound)} .. {write(Threshold.UpperBound)}]";
     246        expression += $" threshold in [{write(Threshold.LowerBound)} .. {write(Threshold.UpperBound)}]";
     247
     248      if (!double.IsNegativeInfinity(DynInterval.LowerBound) && !double.IsPositiveInfinity(DynInterval.UpperBound))
     249        expression += $" start in [{write(DynInterval.LowerBound)} .. {write(DynInterval.UpperBound)}]";
    213250
    214251      return expression;
  • branches/3119_AdditionalShapeConstraintFeatures/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Interval/ShapeConstraintsParser.cs

    r17946 r17995  
    7676    private const string weightRegex = @"\s*(weight:\s*(?<weight>\S*))?";
    7777    private const string thresholdRegex = @"\s*(threshold\s*in\s*(?<threshold> "+ intervalRegex + @"))?";
     78    private const string dynIntervalStartRegex = @"\s*(start\s*in\s*(?<dynInterval> " + intervalRegex + @"))?";
    7879    public static ShapeConstraint ParseFunctionRangeConstraint(string expr) {
    7980      if (!expr.StartsWith("f")) throw new ArgumentException($"Invalid function range constraint {expr} (e.g. f in [1..2])");
     
    9091      // df/d'x' in [0 .. 10] weight: 2.0
    9192      // df / d'x' in [0..10], 'x' in [1 .. 3]
    92       // df / d'x' in [0..10], 'x' in [1 .. 3], y in [10..30] weight: 1.2
    93       // df / d'x' in [0..10], 'x' in [1 .. 3], y in [10..30] weight: 1.2 threshold in [-10 .. 10]
     93      // df / d'x' in [0..10], 'x' in [1 .. 3], 'y' in [10..30] weight: 1.2
     94      // df / d'x' in [0..10], 'x' in [1 .. 3], 'y' in [10..30] weight: 1.2 threshold in [-10 .. 10]
    9495      var match = Regex.Match(targetConstraint,
    9596                    @"\s*\bin\b" +
     
    101102                    @")*" +
    102103                    weightRegex +
    103                     thresholdRegex
     104                    thresholdRegex +
     105                    dynIntervalStartRegex
    104106                    );
    105107
     
    112114        var interval = new Interval(lowerBound, upperBound);
    113115        var weight = 1.0;
    114         var threshold = new Interval(double.NegativeInfinity, double.PositiveInfinity);
     116        var threshold = new Interval(0, 0);
     117        Interval dynInterval = new Interval(double.NegativeInfinity, double.PositiveInfinity);
     118        int intervalIdx = 1;
     119        var lowerboundCount = match.Groups["lowerBound"].Captures.Count;
     120        var upperboundCount = match.Groups["upperBound"].Captures.Count;
    115121
    116122        if (match.Groups["weight"].Success && !string.IsNullOrWhiteSpace(match.Groups["weight"].Value))
    117123          weight = ParseAndValidateDouble(match.Groups["weight"].Value);
    118124
    119         if(match.Groups["threshold"].Success) {
    120           var lowerboundCount = match.Groups["lowerBound"].Captures.Count;
    121           var upperboundCount = match.Groups["upperBound"].Captures.Count;
    122           var thresholdLb = ParseIntervalBounds(match.Groups["lowerBound"].Captures[lowerboundCount - 1].Value);
    123           var thresholdUb = ParseIntervalBounds(match.Groups["upperBound"].Captures[upperboundCount - 1].Value);
     125        if (match.Groups["dynInterval"].Success) {
     126          var dynIntervalLb = ParseIntervalBounds(match.Groups["lowerBound"].Captures[lowerboundCount - intervalIdx].Value);
     127          var dynIntervalUb = ParseIntervalBounds(match.Groups["upperBound"].Captures[upperboundCount - intervalIdx].Value);
     128          intervalIdx++;
     129          dynInterval = new Interval(dynIntervalLb, dynIntervalUb);
     130        }
     131
     132        if (match.Groups["threshold"].Success) {
     133          var thresholdLb = ParseIntervalBounds(match.Groups["lowerBound"].Captures[lowerboundCount - intervalIdx].Value);
     134          var thresholdUb = ParseIntervalBounds(match.Groups["upperBound"].Captures[upperboundCount - intervalIdx].Value);
     135          intervalIdx++;
    124136          threshold = new Interval(thresholdLb, thresholdUb);
    125137        }
     138
    126139
    127140        if (match.Groups["varName"].Success) {
     
    138151              throw new ArgumentException($"The constraint {expr} has multiple regions of the same variable.");
    139152          }
    140           return new ShapeConstraint(interval, regions, weight, threshold);
     153          return new ShapeConstraint(interval, regions, weight, threshold, dynInterval);
    141154        } else
    142           return new ShapeConstraint(interval, weight, threshold);
     155          return new ShapeConstraint(interval, weight, threshold, dynInterval);
    143156      } else
    144157        throw new ArgumentException($"The target constraint {expr} is not valid.");
     
    160173                                  @")*" +
    161174                                weightRegex +
    162                                 thresholdRegex
     175                                thresholdRegex +
     176                                dynIntervalStartRegex
    163177                                );
    164178
     
    184198        var interval = new Interval(lowerBound, upperBound);
    185199        var weight = 1.0;
    186         var threshold = new Interval(double.NegativeInfinity, double.PositiveInfinity);
     200        var threshold = new Interval(0, 0);
     201        Interval dynInterval = new Interval(double.NegativeInfinity, double.PositiveInfinity);
     202        int intervalIdx = 1;
     203        var lowerboundCount = match.Groups["lowerBound"].Captures.Count;
     204        var upperboundCount = match.Groups["upperBound"].Captures.Count;
    187205
    188206        if (match.Groups["weight"].Success && !string.IsNullOrWhiteSpace(match.Groups["weight"].Value))
    189207          weight = ParseAndValidateDouble(match.Groups["weight"].Value);
    190208
     209        if (match.Groups["dynInterval"].Success) {
     210          var dynIntervalLb = ParseIntervalBounds(match.Groups["lowerBound"].Captures[lowerboundCount - intervalIdx].Value);
     211          var dynIntervalUb = ParseIntervalBounds(match.Groups["upperBound"].Captures[upperboundCount - intervalIdx].Value);
     212          intervalIdx++;
     213          dynInterval = new Interval(dynIntervalLb, dynIntervalUb);
     214        }
     215
    191216        if (match.Groups["threshold"].Success) {
    192           var lowerboundCount = match.Groups["lowerBound"].Captures.Count;
    193           var upperboundCount = match.Groups["upperBound"].Captures.Count;
    194           var thresholdLb = ParseIntervalBounds(match.Groups["lowerBound"].Captures[lowerboundCount - 1].Value);
    195           var thresholdUb = ParseIntervalBounds(match.Groups["upperBound"].Captures[upperboundCount - 1].Value);
     217          var thresholdLb = ParseIntervalBounds(match.Groups["lowerBound"].Captures[lowerboundCount - intervalIdx].Value);
     218          var thresholdUb = ParseIntervalBounds(match.Groups["upperBound"].Captures[upperboundCount - intervalIdx].Value);
     219          intervalIdx++;
    196220          threshold = new Interval(thresholdLb, thresholdUb);
    197221        }
     
    210234              throw new ArgumentException($"The constraint {expr} has multiple regions of the same variable.");
    211235          }
    212           return new ShapeConstraint(variable, numberOfDerivation, interval, regions, weight, threshold);
     236          return new ShapeConstraint(variable, numberOfDerivation, interval, regions, weight, threshold, dynInterval);
    213237        } else
    214           return new ShapeConstraint(variable, numberOfDerivation, interval, weight, threshold);
     238          return new ShapeConstraint(variable, numberOfDerivation, interval, weight, threshold, dynInterval);
    215239      } else
    216240        throw new ArgumentException($"The derivation constraint {expr} is not valid.");
Note: See TracChangeset for help on using the changeset viewer.