Changeset 17995
- Timestamp:
- 06/22/21 18:28:36 (3 years ago)
- 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 131 131 <Compile Include="SingleObjective\Evaluators\SymbolicRegressionMeanRelativeErrorEvaluator.cs" /> 132 132 <Compile Include="SingleObjective\SymbolicRegressionSolutionsAnalyzer.cs" /> 133 <Compile Include="SymbolicRegressionMetaModelAnalyzer.cs" /> 133 134 <Compile Include="SymbolicRegressionPhenotypicDiversityAnalyzer.cs" /> 134 135 <Compile Include="SymbolicRegressionPruningAnalyzer.cs" /> … … 158 159 <Compile Include="SingleObjective\Evaluators\SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.cs" /> 159 160 <Compile Include="SymbolicRegressionPruningOperator.cs" /> 161 <Compile Include="SymbolicRegressionSingleObjectiveMetaModelAnalyzer.cs" /> 160 162 <Compile Include="SymbolicRegressionSolution.cs" /> 161 163 <Compile Include="SymbolicRegressionSolutionImpactValuesCalculator.cs" /> -
branches/3119_AdditionalShapeConstraintFeatures/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/Plugin.cs.frame
r17931 r17995 37 37 [PluginDependency("HeuristicLab.Operators", "3.3")] 38 38 [PluginDependency("HeuristicLab.Optimization", "3.3")] 39 [PluginDependency("HeuristicLab.Optimization.Operators", "3.3")] 39 40 [PluginDependency("HeuristicLab.Parameters", "3.3")] 40 41 [PluginDependency("HeuristicLab.Attic", "1.0")] -
branches/3119_AdditionalShapeConstraintFeatures/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/NMSEConstraintsEvaluator.cs
r17914 r17995 24 24 using System.Linq; 25 25 using HEAL.Attic; 26 using HeuristicLab.Analysis; 26 27 using HeuristicLab.Common; 27 28 using HeuristicLab.Core; 28 29 using HeuristicLab.Data; 29 30 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding; 31 using HeuristicLab.Optimization; 32 using HeuristicLab.Optimization.Operators; 30 33 using HeuristicLab.Parameters; 31 34 using HeuristicLab.Problems.DataAnalysis.Symbolic.Regression; … … 39 42 private const string OptimizeParametersParameterName = "OptimizeParameters"; 40 43 private const string ParameterOptimizationIterationsParameterName = "ParameterOptimizationIterations"; 44 private const string UseConstraintsParameterName = "UseConstraintsEvaluation"; 41 45 private const string UseSoftConstraintsParameterName = "UseSoftConstraintsEvaluation"; 42 46 private const string BoundsEstimatorParameterName = "BoundsEstimator"; 43 47 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"; 44 61 45 62 … … 50 67 (IFixedValueParameter<IntValue>)Parameters[ParameterOptimizationIterationsParameterName]; 51 68 69 public IFixedValueParameter<BoolValue> UseConstraintsParameter => 70 (IFixedValueParameter<BoolValue>)Parameters[UseConstraintsParameterName]; 71 52 72 public IFixedValueParameter<BoolValue> UseSoftConstraintsParameter => 53 73 (IFixedValueParameter<BoolValue>)Parameters[UseSoftConstraintsParameterName]; … … 55 75 public IValueParameter<IBoundsEstimator> BoundsEstimatorParameter => 56 76 (IValueParameter<IBoundsEstimator>)Parameters[BoundsEstimatorParameterName]; 77 57 78 public IFixedValueParameter<DoubleValue> PenaltyFactorParameter => 58 79 (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]; 59 126 60 127 public bool OptimizeParameters { … … 68 135 } 69 136 137 public bool UseConstraints { 138 get => UseConstraintsParameter.Value.Value; 139 set => UseConstraintsParameter.Value.Value = value; 140 } 141 70 142 public bool UseSoftConstraints { 71 143 get => UseSoftConstraintsParameter.Value.Value; … … 78 150 } 79 151 80 public double Penal ityFactor {152 public double PenaltyFactor { 81 153 get => PenaltyFactorParameter.Value.Value; 82 154 set => PenaltyFactorParameter.Value.Value = value; 83 155 } 84 156 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 } 85 178 86 179 public override bool Maximization => false; // NMSE is minimized … … 99 192 Parameters.Add(new FixedValueParameter<BoolValue>(OptimizeParametersParameterName, 100 193 "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))); 101 196 Parameters.Add(new FixedValueParameter<IntValue>(ParameterOptimizationIterationsParameterName, 102 197 "Define how many parameter optimization steps should be performed (default: 10).", new IntValue(10))); … … 107 202 Parameters.Add(new FixedValueParameter<DoubleValue>(PenaltyFactorParameterName, 108 203 "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 };*/ 109 240 } 110 241 … … 125 256 var estimationLimits = EstimationLimitsParameter.ActualValue; 126 257 var applyLinearScaling = ApplyLinearScalingParameter.ActualValue.Value; 127 258 128 259 if (OptimizeParameters) { 129 260 SymbolicRegressionConstantOptimizationEvaluator.OptimizeConstants(interpreter, tree, problemData, rows, … … 165 296 166 297 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); 168 306 QualityParameter.ActualValue = new DoubleValue(quality); 169 307 170 308 return base.InstrumentedApply(); 171 309 } 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; 172 322 173 323 public static double Calculate( … … 177 327 IRegressionProblemData problemData, IEnumerable<int> rows, 178 328 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 } 180 364 181 365 var estimatedValues = interpreter.GetSymbolicExpressionTreeValues(tree, problemData.Dataset, rows); … … 189 373 190 374 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 } 192 396 } 193 397 194 398 var constraintViolations = IntervalUtil.GetConstraintViolations(constraints, estimator, intervalCollection, tree); 399 var constraintBounds = IntervalUtil.GetModelBounds(constraints, estimator, intervalCollection, tree); 195 400 196 401 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 }*/ 199 413 200 414 if (useSoftConstraints) { … … 202 416 throw new ArgumentException("The parameter has to be greater or equal 0.0!", nameof(penaltyFactor)); 203 417 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 /* 204 427 var weightedViolationSum = constraints 205 428 .Zip(constraintViolations, (c, v) => c.Weight * v) 206 429 .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); 209 454 } else if (constraintViolations.Any(x => x > 0.0)) { 210 455 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 212 459 213 460 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; 214 506 } 215 507 … … 223 515 var nmse = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree, 224 516 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); 226 522 227 523 SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = null; -
branches/3119_AdditionalShapeConstraintFeatures/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SymbolicRegressionSolution.cs
r17911 r17995 38 38 private const string ModelDepthResultName = "Model Depth"; 39 39 40 private const string ConstraintViolationsResultsResultName = "Constraint Violations Results"; 41 40 42 private const string EstimationLimitsResultsResultName = "Estimation Limits Results"; 41 43 private const string EstimationLimitsResultName = "Estimation Limits"; … … 64 66 get { return ((IntValue)this[ModelDepthResultName].Value).Value; } 65 67 private set { ((IntValue)this[ModelDepthResultName].Value).Value = value; } 68 } 69 70 public ResultCollection ConstraintViolationsResults { 71 get { return (ResultCollection)this[ConstraintViolationsResultsResultName].Value; } 66 72 } 67 73 … … 136 142 estimationLimitResults.Add(new Result(TestNaNEvaluationsResultName, "", new IntValue())); 137 143 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)); 138 151 139 152 if (IntervalInterpreter.IsCompatible(Model.SymbolicExpressionTree)) … … 159 172 estimationLimitResults.Add(new Result(TestNaNEvaluationsResultName, "", new IntValue())); 160 173 Add(new Result(EstimationLimitsResultsResultName, "Results concerning the estimation limits of symbolic regression solution", estimationLimitResults)); 174 161 175 CalculateResults(); 162 176 } … … 178 192 ModelLength = Model.SymbolicExpressionTree.Length; 179 193 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 */ 180 219 181 220 EstimationLimits.Lower = Model.LowerEstimationLimit; -
branches/3119_AdditionalShapeConstraintFeatures/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/IntervalUtil.cs
r17906 r17995 28 28 namespace HeuristicLab.Problems.DataAnalysis.Symbolic { 29 29 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 30 44 public static IEnumerable<double> GetConstraintViolations( 31 45 IEnumerable<ShapeConstraint> constraints, IBoundsEstimator estimator, IntervalCollection intervalCollection, … … 37 51 ShapeConstraint constraint, IBoundsEstimator estimator, IntervalCollection variableRanges, 38 52 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) { 39 86 var varRanges = variableRanges.GetReadonlyDictionary(); 40 87 … … 55 102 } 56 103 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; 70 105 } 71 106 } -
branches/3119_AdditionalShapeConstraintFeatures/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Interval/ShapeConstraint.cs
r17946 r17995 107 107 108 108 [Storable] 109 private Interval threshold ;109 private Interval threshold = new Interval(0, 0); 110 110 public Interval Threshold { 111 111 get => threshold; … … 114 114 return; 115 115 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; 116 143 OnToStringChanged(); 117 144 OnChanged(); … … 125 152 private void AfterDeserialization() { 126 153 if (regions != null) regions.Changed += regions_Changed; 154 if (TargetInterval == null) 155 TargetInterval = new Interval(interval.LowerBound, interval.UpperBound); 127 156 } 128 157 129 158 // without derivation 130 public ShapeConstraint(Interval interval, double weight, Interval threshold )159 public ShapeConstraint(Interval interval, double weight, Interval threshold, Interval dynInterval) 131 160 : 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) 135 164 : this(string.Empty, 0, 136 interval, regions, weight, threshold ) { }165 interval, regions, weight, threshold, dynInterval) { } 137 166 138 167 public ShapeConstraint(string variable, int numberOfDerivations, 139 Interval interval, double weight, Interval threshold )168 Interval interval, double weight, Interval threshold, Interval dynInterval) 140 169 : this(variable, numberOfDerivations, 141 interval, new IntervalCollection(), weight, threshold ) { }170 interval, new IntervalCollection(), weight, threshold, dynInterval) { } 142 171 143 172 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) { 145 174 Variable = variable; 146 175 NumberOfDerivations = numberOfDerivations; … … 149 178 Weight = weight; 150 179 Threshold = threshold; 180 DynInterval = dynInterval; 181 TargetInterval = new Interval(interval.LowerBound, interval.UpperBound); 151 182 } 152 183 … … 162 193 Regions = cloner.Clone(original.Regions); 163 194 Weight = original.weight; 164 } 165 195 Threshold = original.Threshold; 196 DynInterval = original.DynInterval; 197 TargetInterval = original.TargetInterval; 198 } 166 199 167 200 public event EventHandler Changed; … … 188 221 string write(double val) => double.IsPositiveInfinity(val) ? "inf." : double.IsNegativeInfinity(val) ? "-inf." : $"{val}"; 189 222 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)}]"); 191 224 } else { 192 225 var derivationString = string.Empty; … … 199 232 derivationString = "³"; break; 200 233 } 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)}]"); 202 235 } 203 236 … … 209 242 expression += $" weight: {weight}"; 210 243 } 244 211 245 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)}]"; 213 250 214 251 return expression; -
branches/3119_AdditionalShapeConstraintFeatures/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Interval/ShapeConstraintsParser.cs
r17946 r17995 76 76 private const string weightRegex = @"\s*(weight:\s*(?<weight>\S*))?"; 77 77 private const string thresholdRegex = @"\s*(threshold\s*in\s*(?<threshold> "+ intervalRegex + @"))?"; 78 private const string dynIntervalStartRegex = @"\s*(start\s*in\s*(?<dynInterval> " + intervalRegex + @"))?"; 78 79 public static ShapeConstraint ParseFunctionRangeConstraint(string expr) { 79 80 if (!expr.StartsWith("f")) throw new ArgumentException($"Invalid function range constraint {expr} (e.g. f in [1..2])"); … … 90 91 // df/d'x' in [0 .. 10] weight: 2.0 91 92 // df / d'x' in [0..10], 'x' in [1 .. 3] 92 // df / d'x' in [0..10], 'x' in [1 .. 3], yin [10..30] weight: 1.293 // df / d'x' in [0..10], 'x' in [1 .. 3], yin [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] 94 95 var match = Regex.Match(targetConstraint, 95 96 @"\s*\bin\b" + … … 101 102 @")*" + 102 103 weightRegex + 103 thresholdRegex 104 thresholdRegex + 105 dynIntervalStartRegex 104 106 ); 105 107 … … 112 114 var interval = new Interval(lowerBound, upperBound); 113 115 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; 115 121 116 122 if (match.Groups["weight"].Success && !string.IsNullOrWhiteSpace(match.Groups["weight"].Value)) 117 123 weight = ParseAndValidateDouble(match.Groups["weight"].Value); 118 124 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++; 124 136 threshold = new Interval(thresholdLb, thresholdUb); 125 137 } 138 126 139 127 140 if (match.Groups["varName"].Success) { … … 138 151 throw new ArgumentException($"The constraint {expr} has multiple regions of the same variable."); 139 152 } 140 return new ShapeConstraint(interval, regions, weight, threshold );153 return new ShapeConstraint(interval, regions, weight, threshold, dynInterval); 141 154 } else 142 return new ShapeConstraint(interval, weight, threshold );155 return new ShapeConstraint(interval, weight, threshold, dynInterval); 143 156 } else 144 157 throw new ArgumentException($"The target constraint {expr} is not valid."); … … 160 173 @")*" + 161 174 weightRegex + 162 thresholdRegex 175 thresholdRegex + 176 dynIntervalStartRegex 163 177 ); 164 178 … … 184 198 var interval = new Interval(lowerBound, upperBound); 185 199 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; 187 205 188 206 if (match.Groups["weight"].Success && !string.IsNullOrWhiteSpace(match.Groups["weight"].Value)) 189 207 weight = ParseAndValidateDouble(match.Groups["weight"].Value); 190 208 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 191 216 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++; 196 220 threshold = new Interval(thresholdLb, thresholdUb); 197 221 } … … 210 234 throw new ArgumentException($"The constraint {expr} has multiple regions of the same variable."); 211 235 } 212 return new ShapeConstraint(variable, numberOfDerivation, interval, regions, weight, threshold );236 return new ShapeConstraint(variable, numberOfDerivation, interval, regions, weight, threshold, dynInterval); 213 237 } else 214 return new ShapeConstraint(variable, numberOfDerivation, interval, weight, threshold );238 return new ShapeConstraint(variable, numberOfDerivation, interval, weight, threshold, dynInterval); 215 239 } else 216 240 throw new ArgumentException($"The derivation constraint {expr} is not valid.");
Note: See TracChangeset
for help on using the changeset viewer.