Changeset 17891
- Timestamp:
- 03/12/21 16:41:42 (4 years ago)
- Location:
- branches/3073_IA_constraint_splitting_reintegration
- Files:
-
- 12 edited
- 4 moved
Legend:
- Unmodified
- Added
- Removed
-
branches/3073_IA_constraint_splitting_reintegration
- Property svn:ignore
-
old new 1 1 bin 2 TestResults
-
- Property svn:ignore
-
branches/3073_IA_constraint_splitting_reintegration/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj
r17772 r17891 237 237 <Compile Include="Interpreter\BatchInstruction.cs" /> 238 238 <Compile Include="Interpreter\BatchOperations.cs" /> 239 <Compile Include="Interpreter\IABoundsEstimator.cs" /> 239 <Compile Include="Interpreter\IntervalArithBoundsEstimator.cs" /> 240 <Compile Include="Interpreter\IntervalArithCompiledExpressionBoundsEstimator.cs" /> 240 241 <Compile Include="Interpreter\IntervalInterpreter.cs" /> 241 242 <Compile Include="Interpreter\SymbolicDataAnalysisExpressionCompiledTreeInterpreter.cs" /> 242 243 <Compile Include="Interpreter\SymbolicDataAnalysisExpressionTreeBatchInterpreter.cs" /> 243 <Compile Include="Interpreter\IACompiledExpressionBoundsEstimator.cs" />244 244 <Compile Include="Interpreter\SymbolicDataAnalysisExpressionTreeNativeInterpreter.cs" /> 245 245 <Compile Include="IntervalUtil.cs" /> -
branches/3073_IA_constraint_splitting_reintegration/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interfaces/IBoundsEstimator.cs
r17887 r17891 13 13 14 14 // returns the size of the violation which is the distance to one of the bounds 15 double CheckConstraint(15 double GetConstraintViolation( 16 16 ISymbolicExpressionTree tree, IntervalCollection variableRanges, ShapeConstraint constraint); 17 17 -
branches/3073_IA_constraint_splitting_reintegration/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/IntervalArithBoundsEstimator.cs
r17890 r17891 12 12 namespace HeuristicLab.Problems.DataAnalysis.Symbolic { 13 13 [StorableType("C8539434-6FB0-47D0-9F5A-2CAE5D8B8B4F")] 14 [Item("I ABounds Estimator", "Interpreter for calculation of intervals of symbolic models.")]15 public sealed class I ABoundsEstimator : ParameterizedNamedItem, IBoundsEstimator {14 [Item("Interval Arithmetic Bounds Estimator", "Interpreter for calculation of intervals of symbolic models.")] 15 public sealed class IntervalArithBoundsEstimator : ParameterizedNamedItem, IBoundsEstimator { 16 16 #region Parameters 17 17 18 18 private const string EvaluatedSolutionsParameterName = "EvaluatedSolutions"; 19 private const string UseIntervalSplittingParameterName = "Use Interval splitting";20 private const string SplittingIterationsParameterName = "Splitting Iterations";21 private const string SplittingWidthParameterName = "Splitting width";22 19 23 20 public IFixedValueParameter<IntValue> EvaluatedSolutionsParameter => 24 (IFixedValueParameter<IntValue>) Parameters[EvaluatedSolutionsParameterName]; 25 26 public IFixedValueParameter<BoolValue> UseIntervalSplittingParameter => 27 (IFixedValueParameter<BoolValue>) Parameters[UseIntervalSplittingParameterName]; 28 29 public IFixedValueParameter<IntValue> SplittingIterationsParameter => 30 (IFixedValueParameter<IntValue>) Parameters[SplittingIterationsParameterName]; 31 32 public IFixedValueParameter<DoubleValue> SplittingWidthParameter => 33 (IFixedValueParameter<DoubleValue>) Parameters[SplittingWidthParameterName]; 21 (IFixedValueParameter<IntValue>)Parameters[EvaluatedSolutionsParameterName]; 34 22 35 23 public int EvaluatedSolutions { … … 37 25 set => EvaluatedSolutionsParameter.Value.Value = value; 38 26 } 39 40 public bool UseIntervalSplitting {41 get => UseIntervalSplittingParameter.Value.Value;42 set => UseIntervalSplittingParameter.Value.Value = value;43 }44 45 public int SplittingIterations {46 get => SplittingIterationsParameter.Value.Value;47 set => SplittingIterationsParameter.Value.Value = value;48 }49 50 public double SplittingWidth {51 get => SplittingWidthParameter.Value.Value;52 set => SplittingWidthParameter.Value.Value = value;53 }54 55 27 #endregion 56 28 … … 58 30 59 31 [StorableConstructor] 60 private I ABoundsEstimator(StorableConstructorFlag _) : base(_) { }61 62 private I ABoundsEstimator(IABoundsEstimator original, Cloner cloner) : base(original, cloner) { }63 64 public I ABoundsEstimator() : base("IA Bounds Estimator",32 private IntervalArithBoundsEstimator(StorableConstructorFlag _) : base(_) { } 33 34 private IntervalArithBoundsEstimator(IntervalArithBoundsEstimator original, Cloner cloner) : base(original, cloner) { } 35 36 public IntervalArithBoundsEstimator() : base("IA Bounds Estimator", 65 37 "Estimates the bounds of the model with interval arithmetic") { 66 38 Parameters.Add(new FixedValueParameter<IntValue>(EvaluatedSolutionsParameterName, 67 39 "A counter for the total number of solutions the estimator has evaluated.", new IntValue(0))); 68 Parameters.Add(new FixedValueParameter<BoolValue>(UseIntervalSplittingParameterName,69 "Defines whether interval splitting is activated or not.", new BoolValue(false)));70 Parameters.Add(new FixedValueParameter<IntValue>(SplittingIterationsParameterName,71 "Defines the number of iterations of splitting.", new IntValue(200)));72 Parameters.Add(new FixedValueParameter<DoubleValue>(SplittingWidthParameterName,73 "Width of interval, after the splitting should stop.", new DoubleValue(0.0)));74 40 } 75 41 76 42 public override IDeepCloneable Clone(Cloner cloner) { 77 return new I ABoundsEstimator(this, cloner);43 return new IntervalArithBoundsEstimator(this, cloner); 78 44 } 79 45 … … 98 64 IDictionary<string, Interval> variableRanges) { 99 65 if (variableRanges == null) 100 throw new ArgumentNullException("No variable wranges are present!", nameof(variableRanges));101 102 // Check if all variables used in the tree are present in the dataset66 throw new ArgumentNullException("No variable ranges are present!", nameof(variableRanges)); 67 68 // Check if all variables used in the tree are present in the dataset 103 69 foreach (var variable in tree.IterateNodesPrefix().OfType<VariableTreeNode>().Select(n => n.VariableName) 104 70 .Distinct()) … … 108 74 var code = SymbolicExpressionTreeCompiler.Compile(tree, OpCodes.MapSymbolToOpCode); 109 75 foreach (var instr in code.Where(i => i.opCode == OpCodes.Variable)) { 110 var variableTreeNode = (VariableTreeNode) 76 var variableTreeNode = (VariableTreeNode)instr.dynamicNode; 111 77 instr.data = variableRanges[variableTreeNode.VariableName]; 112 78 } … … 115 81 } 116 82 83 // Use ref parameter, because the tree will be iterated through recursively from the left-side branch to the right side 84 // Update instructionCounter, whenever Evaluate is called 117 85 public static Interval Evaluate( 118 86 Instruction[] instructions, ref int instructionCounter, … … 120 88 IDictionary<string, Interval> variableIntervals = null) { 121 89 var currentInstr = instructions[instructionCounter]; 122 //Use ref parameter, because the tree will be iterated through recursively from the left-side branch to the right side123 //Update instructionCounter, whenever Evaluate is called124 90 instructionCounter++; 125 Interval result = null;91 Interval result; 126 92 127 93 switch (currentInstr.opCode) { 128 //Variables, Constants, ...129 94 case OpCodes.Variable: { 130 var variableTreeNode = (VariableTreeNode)currentInstr.dynamicNode;131 var weightInterval = new Interval(variableTreeNode.Weight, variableTreeNode.Weight);132 133 Interval variableInterval;134 if (variableIntervals != null && variableIntervals.ContainsKey(variableTreeNode.VariableName))135 variableInterval = variableIntervals[variableTreeNode.VariableName];136 else137 variableInterval = (Interval)currentInstr.data;138 139 result = Interval.Multiply(variableInterval, weightInterval);140 break;141 }95 var variableTreeNode = (VariableTreeNode)currentInstr.dynamicNode; 96 var weightInterval = new Interval(variableTreeNode.Weight, variableTreeNode.Weight); 97 98 Interval variableInterval; 99 if (variableIntervals != null && variableIntervals.ContainsKey(variableTreeNode.VariableName)) 100 variableInterval = variableIntervals[variableTreeNode.VariableName]; 101 else 102 variableInterval = (Interval)currentInstr.data; 103 104 result = Interval.Multiply(variableInterval, weightInterval); 105 break; 106 } 142 107 case OpCodes.Constant: { 143 var constTreeNode = (ConstantTreeNode) currentInstr.dynamicNode; 144 result = new Interval(constTreeNode.Value, constTreeNode.Value); 145 break; 146 } 147 //Elementary arithmetic rules 108 var constTreeNode = (ConstantTreeNode)currentInstr.dynamicNode; 109 result = new Interval(constTreeNode.Value, constTreeNode.Value); 110 break; 111 } 148 112 case OpCodes.Add: { 149 result = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);150 for (var i = 1; i < currentInstr.nArguments; i++) {151 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);152 result = Interval.Add(result, argumentInterval);153 }154 155 break;156 }113 result = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 114 for (var i = 1; i < currentInstr.nArguments; i++) { 115 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 116 result = Interval.Add(result, argumentInterval); 117 } 118 119 break; 120 } 157 121 case OpCodes.Sub: { 158 result = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);159 if (currentInstr.nArguments == 1)160 result = Interval.Multiply(new Interval(-1, -1), result);161 162 for (var i = 1; i < currentInstr.nArguments; i++) {163 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);164 result = Interval.Subtract(result, argumentInterval);165 }166 167 break;168 }122 result = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 123 if (currentInstr.nArguments == 1) 124 result = Interval.Multiply(new Interval(-1, -1), result); 125 126 for (var i = 1; i < currentInstr.nArguments; i++) { 127 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 128 result = Interval.Subtract(result, argumentInterval); 129 } 130 131 break; 132 } 169 133 case OpCodes.Mul: { 170 result = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);171 for (var i = 1; i < currentInstr.nArguments; i++) {172 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);173 result = Interval.Multiply(result, argumentInterval);174 }175 176 break;177 }134 result = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 135 for (var i = 1; i < currentInstr.nArguments; i++) { 136 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 137 result = Interval.Multiply(result, argumentInterval); 138 } 139 140 break; 141 } 178 142 case OpCodes.Div: { 179 result = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 180 if (currentInstr.nArguments == 1) 181 result = Interval.Divide(new Interval(1, 1), result); 182 183 for (var i = 1; i < currentInstr.nArguments; i++) { 184 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 185 result = Interval.Divide(result, argumentInterval); 186 } 187 188 break; 189 } 190 //Trigonometric functions 143 result = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 144 if (currentInstr.nArguments == 1) 145 result = Interval.Divide(new Interval(1, 1), result); 146 147 for (var i = 1; i < currentInstr.nArguments; i++) { 148 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 149 result = Interval.Divide(result, argumentInterval); 150 } 151 152 break; 153 } 191 154 case OpCodes.Sin: { 192 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);193 result = Interval.Sine(argumentInterval);194 break;195 }155 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 156 result = Interval.Sine(argumentInterval); 157 break; 158 } 196 159 case OpCodes.Cos: { 197 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);198 result = Interval.Cosine(argumentInterval);199 break;200 }160 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 161 result = Interval.Cosine(argumentInterval); 162 break; 163 } 201 164 case OpCodes.Tan: { 202 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);203 result = Interval.Tangens(argumentInterval);204 break;205 }165 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 166 result = Interval.Tangens(argumentInterval); 167 break; 168 } 206 169 case OpCodes.Tanh: { 207 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 208 result = Interval.HyperbolicTangent(argumentInterval); 209 break; 210 } 211 //Exponential functions 170 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 171 result = Interval.HyperbolicTangent(argumentInterval); 172 break; 173 } 212 174 case OpCodes.Log: { 213 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);214 result = Interval.Logarithm(argumentInterval);215 break;216 }175 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 176 result = Interval.Logarithm(argumentInterval); 177 break; 178 } 217 179 case OpCodes.Exp: { 218 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);219 result = Interval.Exponential(argumentInterval);220 break;221 }180 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 181 result = Interval.Exponential(argumentInterval); 182 break; 183 } 222 184 case OpCodes.Square: { 223 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);224 result = Interval.Square(argumentInterval);225 break;226 }185 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 186 result = Interval.Square(argumentInterval); 187 break; 188 } 227 189 case OpCodes.SquareRoot: { 228 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);229 result = Interval.SquareRoot(argumentInterval);230 break;231 }190 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 191 result = Interval.SquareRoot(argumentInterval); 192 break; 193 } 232 194 case OpCodes.Cube: { 233 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);234 result = Interval.Cube(argumentInterval);235 break;236 }195 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 196 result = Interval.Cube(argumentInterval); 197 break; 198 } 237 199 case OpCodes.CubeRoot: { 238 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);239 result = Interval.CubicRoot(argumentInterval);240 break;241 }200 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 201 result = Interval.CubicRoot(argumentInterval); 202 break; 203 } 242 204 case OpCodes.Absolute: { 243 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);244 result = Interval.Absolute(argumentInterval);245 break;246 }205 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 206 result = Interval.Absolute(argumentInterval); 207 break; 208 } 247 209 case OpCodes.AnalyticQuotient: { 248 result = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);249 for (var i = 1; i < currentInstr.nArguments; i++) {250 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);251 result = Interval.AnalyticalQuotient(result, argumentInterval);252 }253 254 break;255 }210 result = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 211 for (var i = 1; i < currentInstr.nArguments; i++) { 212 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 213 result = Interval.AnalyticalQuotient(result, argumentInterval); 214 } 215 216 break; 217 } 256 218 default: 257 219 throw new NotSupportedException( … … 277 239 } 278 240 279 private static bool ContainsVariableMultipleTimes(ISymbolicExpressionTree tree, out List<String> variables) { 280 variables = new List<string>(); 281 var varlist = tree.IterateNodesPrefix().OfType<VariableTreeNode>().GroupBy(x => x.VariableName); 282 foreach (var group in varlist) { 283 if (group.Count() > 1) { 284 variables.Add(group.Key); 285 } 286 } 287 288 return varlist.Any(group => group.Count() > 1); 289 } 290 291 // a multi-dimensional box with an associated bound 292 // boxbounds are ordered first by bound (smaller first), then by size of box (larger first) then by distance of bottom left corner to origin 293 private class BoxBound : IComparable<BoxBound> { 294 public List<Interval> box; 295 public double bound; 296 297 public BoxBound(IEnumerable<Interval> box, double bound) { 298 this.box = new List<Interval>(box); 299 this.bound = bound; 300 } 301 302 public int CompareTo(BoxBound other) { 303 if (bound != other.bound) return bound.CompareTo(other.bound); 304 305 var thisSize = box.Aggregate(1.0, (current, dimExtent) => current * dimExtent.Width); 306 var otherSize = other.box.Aggregate(1.0, (current, dimExtent) => current * dimExtent.Width); 307 if (thisSize != otherSize) return -thisSize.CompareTo(otherSize); 308 309 var thisDist = box.Sum(dimExtent => dimExtent.LowerBound * dimExtent.LowerBound); 310 var otherDist = other.box.Sum(dimExtent => dimExtent.LowerBound * dimExtent.LowerBound); 311 if (thisDist != otherDist) return thisDist.CompareTo(otherDist); 312 313 // which is smaller first along the dimensions? 314 for (int i = 0; i < box.Count; i++) { 315 if (box[i].LowerBound != other.box[i].LowerBound) return box[i].LowerBound.CompareTo(other.box[i].LowerBound); 316 } 317 318 return 0; 319 } 320 } 321 322 #endregion 323 324 #region Splitting 325 326 public static Interval EvaluateWithSplitting(Instruction[] instructions, 327 IDictionary<string, Interval> variableIntervals, 328 List<string> multipleOccurenceVariables, int splittingIterations, 329 double splittingWidth, 330 IDictionary<ISymbolicExpressionTreeNode, Interval> nodeIntervals = 331 null) { 332 var min = FindBound(instructions, variableIntervals.ToDictionary(entry => entry.Key, entry => entry.Value), 333 multipleOccurenceVariables, splittingIterations, splittingWidth, nodeIntervals, 334 minimization: true); 335 var max = FindBound(instructions, variableIntervals.ToDictionary(entry => entry.Key, entry => entry.Value), 336 multipleOccurenceVariables, splittingIterations, splittingWidth, nodeIntervals, 337 minimization: false); 338 339 return new Interval(min, max); 340 } 341 342 private static double FindBound(Instruction[] instructions, 343 IDictionary<string, Interval> variableIntervals, 344 List<string> multipleOccurenceVariables, int splittingIterations, 345 double splittingWidth, 346 IDictionary<ISymbolicExpressionTreeNode, Interval> nodeIntervals = null, 347 bool minimization = true, bool stopAtLimit = false, double limit = 0) { 348 SortedSet<BoxBound> prioQ = new SortedSet<BoxBound>(); 349 var ic = 0; 350 var stop = false; 351 //Calculate full box 352 var interval = Evaluate(instructions, ref ic, nodeIntervals, variableIntervals: variableIntervals); 353 // the order of keys in a dictionary is guaranteed to be the same order as values in a dictionary 354 // https://docs.microsoft.com/en-us/dotnet/api/system.collections.idictionary.keys?view=netcore-3.1#remarks 355 //var box = variableIntervals.Values; 356 //Box only contains intervals from multiple occurence variables 357 var box = multipleOccurenceVariables.Select(k => variableIntervals[k]); 358 if (minimization) { 359 prioQ.Add(new BoxBound(box, interval.LowerBound)); 360 if (stopAtLimit && interval.LowerBound >= limit) stop = true; 361 } else { 362 prioQ.Add(new BoxBound(box, -interval.UpperBound)); 363 if (stopAtLimit && interval.UpperBound <= limit) stop = true; 364 } 365 366 var discardedBound = double.MaxValue; 367 var runningBound = double.MaxValue; 368 for (var depth = 0; depth < splittingIterations && prioQ.Count > 0 && !stop; ++depth) { 369 var currentBound = prioQ.Min; 370 prioQ.Remove(currentBound); 371 372 if (currentBound.box.All(x => x.Width < splittingWidth)) { 373 discardedBound = Math.Min(discardedBound, currentBound.bound); 374 continue; 375 } 376 377 var newBoxes = Split(currentBound.box, splittingWidth); 378 379 var innerBound = double.MaxValue; 380 foreach (var newBox in newBoxes) { 381 //var intervalEnum = newBox.GetEnumerator(); 382 //var keyEnum = readonlyRanges.Keys.GetEnumerator(); 383 //while (intervalEnum.MoveNext() & keyEnum.MoveNext()) { 384 // variableIntervals[keyEnum.Current] = intervalEnum.Current; 385 //} 386 //Set the splitted variables 387 var intervalEnum = newBox.GetEnumerator(); 388 foreach (var key in multipleOccurenceVariables) { 389 intervalEnum.MoveNext(); 390 variableIntervals[key] = intervalEnum.Current; 391 } 392 393 ic = 0; 394 var res = Evaluate(instructions, ref ic, nodeIntervals, 395 new ReadOnlyDictionary<string, Interval>(variableIntervals)); 396 397 var boxBound = new BoxBound(newBox, minimization ? res.LowerBound : -res.UpperBound); 398 prioQ.Add(boxBound); 399 innerBound = Math.Min(innerBound, boxBound.bound); 400 } 401 402 runningBound = innerBound; 403 404 if (minimization) { 405 if (stopAtLimit && innerBound >= limit) 406 stop = true; 407 } else { 408 if (stopAtLimit && innerBound <= limit) 409 stop = true; 410 } 411 } 412 413 var bound = Math.Min(runningBound, discardedBound); 414 if (bound == double.MaxValue) 415 return minimization ? interval.LowerBound : interval.UpperBound; 416 417 return minimization ? bound : -bound; 418 //return minimization ? prioQ.First().bound : -prioQ.First().bound; 419 } 420 421 private static IEnumerable<IEnumerable<Interval>> Split(List<Interval> box) { 422 var boxes = box.Select(region => region.Split()) 423 .Select(split => new List<Interval> {split.Item1, split.Item2}) 424 .ToList(); 425 426 return boxes.CartesianProduct(); 427 } 428 429 private static IEnumerable<IEnumerable<Interval>> Split(List<Interval> box, double minWidth) { 430 List<Interval> toList(Tuple<Interval, Interval> t) => new List<Interval> {t.Item1, t.Item2}; 431 var boxes = box.Select(region => region.Width > minWidth ? toList(region.Split()) : new List<Interval> {region}) 432 .ToList(); 433 434 return boxes.CartesianProduct(); 435 } 436 437 #endregion 438 241 #endregion 242 439 243 public Interval GetModelBound(ISymbolicExpressionTree tree, IntervalCollection variableRanges) { 440 244 lock (syncRoot) { … … 445 249 var instructions = PrepareInterpreterState(tree, occuringVariableRanges); 446 250 Interval resultInterval; 447 if (!UseIntervalSplitting) { 448 var instructionCounter = 0; 449 resultInterval = Evaluate(instructions, ref instructionCounter, variableIntervals: occuringVariableRanges); 450 } else { 451 var vars = ContainsVariableMultipleTimes(tree, out var variables); 452 resultInterval = EvaluateWithSplitting(instructions, occuringVariableRanges, variables, SplittingIterations, 453 SplittingWidth); 454 } 251 var instructionCounter = 0; 252 resultInterval = Evaluate(instructions, ref instructionCounter, variableIntervals: occuringVariableRanges); 455 253 456 254 // because of numerical errors the bounds might be incorrect … … 466 264 } 467 265 468 public double CheckConstraint(266 public double GetConstraintViolation( 469 267 ISymbolicExpressionTree tree, IntervalCollection variableRanges, ShapeConstraint constraint) { 470 268 var occuringVariableRanges = GetOccurringVariableRanges(tree, variableRanges); 471 269 var instructions = PrepareInterpreterState(tree, occuringVariableRanges); 472 if (!UseIntervalSplitting) { 473 var instructionCounter = 0; 474 var modelBound = Evaluate(instructions, ref instructionCounter, variableIntervals: occuringVariableRanges); 475 if (constraint.Interval.Contains(modelBound)) return 0.0; 476 477 478 var error = 0.0; 479 480 if (!constraint.Interval.Contains(modelBound.LowerBound)) { 481 error += Math.Abs(modelBound.LowerBound - constraint.Interval.LowerBound); 482 } 483 484 if (!constraint.Interval.Contains(modelBound.UpperBound)) { 485 error += Math.Abs(modelBound.UpperBound - constraint.Interval.UpperBound); 486 } 487 488 return error; 489 // return Math.Abs(modelBound.LowerBound - constraint.Interval.LowerBound) + 490 //Math.Abs(modelBound.UpperBound - constraint.Interval.UpperBound); 491 } 492 493 if (double.IsNegativeInfinity(constraint.Interval.LowerBound) && 494 double.IsPositiveInfinity(constraint.Interval.UpperBound)) { 495 return 0.0; 496 } 497 498 ContainsVariableMultipleTimes(tree, out var variables); 499 500 var upperBound = 0.0; 501 var lowerBound = 0.0; 502 if (double.IsNegativeInfinity(constraint.Interval.LowerBound)) { 503 upperBound = FindBound(instructions, occuringVariableRanges, variables, SplittingIterations, SplittingWidth, 504 minimization: false, stopAtLimit: true, limit: constraint.Interval.UpperBound); 505 506 return upperBound <= constraint.Interval.UpperBound 507 ? 0.0 508 : Math.Abs(upperBound - constraint.Interval.UpperBound); 509 } 510 511 if (double.IsPositiveInfinity(constraint.Interval.UpperBound)) { 512 lowerBound = FindBound(instructions, occuringVariableRanges, variables, SplittingIterations, SplittingWidth, 513 minimization: true, stopAtLimit: true, limit: constraint.Interval.LowerBound); 514 515 return lowerBound >= constraint.Interval.LowerBound 516 ? 0.0 517 : Math.Abs(lowerBound - constraint.Interval.LowerBound); 518 } 519 520 upperBound = FindBound(instructions, occuringVariableRanges, variables, SplittingIterations, SplittingWidth, 521 minimization: false, stopAtLimit: true, limit: constraint.Interval.UpperBound); 522 lowerBound = FindBound(instructions, occuringVariableRanges, variables, SplittingIterations, SplittingWidth, 523 minimization: true, stopAtLimit: true, limit: constraint.Interval.LowerBound); 524 525 526 var res = 0.0; 527 528 res += upperBound <= constraint.Interval.UpperBound ? 0.0 : Math.Abs(upperBound - constraint.Interval.UpperBound); 529 res += lowerBound <= constraint.Interval.LowerBound ? 0.0 : Math.Abs(lowerBound - constraint.Interval.LowerBound); 530 531 return res; 270 var instructionCounter = 0; 271 var modelBound = Evaluate(instructions, ref instructionCounter, variableIntervals: occuringVariableRanges); 272 if (constraint.Interval.Contains(modelBound)) return 0.0; 273 274 275 var error = 0.0; 276 277 if (!constraint.Interval.Contains(modelBound.LowerBound)) { 278 error += Math.Abs(modelBound.LowerBound - constraint.Interval.LowerBound); 279 } 280 281 if (!constraint.Interval.Contains(modelBound.UpperBound)) { 282 error += Math.Abs(modelBound.UpperBound - constraint.Interval.UpperBound); 283 } 284 285 return error; 532 286 } 533 287 -
branches/3073_IA_constraint_splitting_reintegration/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/IntervalArithCompiledExpressionBoundsEstimator.cs
r17890 r17891 1 1 using HEAL.Attic; 2 3 2 using HeuristicLab.Common; 4 3 using HeuristicLab.Core; … … 6 5 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding; 7 6 using HeuristicLab.Parameters; 8 9 7 using System; 10 8 using System.Collections.Generic; … … 12 10 using System.Linq.Expressions; 13 11 14 namespace HeuristicLab.Problems.DataAnalysis.Symbolic 15 { 12 namespace HeuristicLab.Problems.DataAnalysis.Symbolic { 16 13 [StorableType("60015D64-5D8B-408A-90A1-E4111BC114D4")] 17 [Item("IA Compiled Expression Bounds Estimator", "Compile a symbolic model into a lambda and use it to evaluate model bounds.")] 18 public class IACompiledExpressionBoundsEstimator : ParameterizedNamedItem, IBoundsEstimator 19 { 14 [Item("Interval Arithmetic Compiled Expression Bounds Estimator", "Compile a symbolic model into a lambda and use it to evaluate model bounds.")] 15 public class IntervalArithCompiledExpressionBoundsEstimator : ParameterizedNamedItem, IBoundsEstimator { 20 16 // interval method names 21 17 private static readonly Dictionary<byte, string> methodName = new Dictionary<byte, string>() { … … 39 35 40 36 private const string EvaluatedSolutionsParameterName = "EvaluatedSolutions"; 41 private const string UseIntervalSplittingParameterName = "Use Interval splitting";42 private const string MaxSplitParameterName = "MaxSplit";43 private const string MinWidthParameterName = "MinWidth";44 45 37 public IFixedValueParameter<IntValue> EvaluatedSolutionsParameter { 46 38 get => (IFixedValueParameter<IntValue>)Parameters[EvaluatedSolutionsParameterName]; 47 39 } 48 49 public IFixedValueParameter<BoolValue> UseIntervalSplittingParameter {50 get => (IFixedValueParameter<BoolValue>)Parameters[UseIntervalSplittingParameterName];51 }52 53 public IFixedValueParameter<IntValue> MaxSplitParameter {54 get => (IFixedValueParameter<IntValue>)Parameters[MaxSplitParameterName];55 }56 57 public IFixedValueParameter<DoubleValue> MinWidthParameter {58 get => (IFixedValueParameter<DoubleValue>)Parameters[MinWidthParameterName];59 }60 61 public int MaxSplit {62 get => MaxSplitParameter.Value.Value;63 set => MaxSplitParameter.Value.Value = value;64 }65 66 public double MinWidth {67 get => MinWidthParameter.Value.Value;68 set => MinWidthParameter.Value.Value = value;69 }70 71 40 public int EvaluatedSolutions { 72 41 get => EvaluatedSolutionsParameter.Value.Value; … … 74 43 } 75 44 76 public bool UseIntervalSplitting {77 get => UseIntervalSplittingParameter.Value.Value;78 set => UseIntervalSplittingParameter.Value.Value = value;79 }80 81 45 private readonly object syncRoot = new object(); 82 46 83 public I ACompiledExpressionBoundsEstimator() : base("IABounds Estimator",47 public IntervalArithCompiledExpressionBoundsEstimator() : base("Interval Arith Bounds Estimator", 84 48 "Estimates the bounds of the model with interval arithmetic, by first compiling the model into a lambda.") { 85 49 Parameters.Add(new FixedValueParameter<IntValue>(EvaluatedSolutionsParameterName, 86 50 "A counter for the total number of solutions the estimator has evaluated.", new IntValue(0))); 87 Parameters.Add(new FixedValueParameter<BoolValue>(UseIntervalSplittingParameterName,88 "Defines whether interval splitting is activated or not.", new BoolValue(false)));89 Parameters.Add(new FixedValueParameter<IntValue>(MaxSplitParameterName,90 "Defines the number of iterations of splitting.", new IntValue(200)));91 Parameters.Add(new FixedValueParameter<DoubleValue>(MinWidthParameterName,92 "Width of interval, after the splitting should stop.", new DoubleValue(0.0)));93 51 } 94 52 95 53 [StorableConstructor] 96 private I ACompiledExpressionBoundsEstimator(StorableConstructorFlag _) : base(_) { }97 98 private I ACompiledExpressionBoundsEstimator(IACompiledExpressionBoundsEstimator original, Cloner cloner) : base(original, cloner) { }54 private IntervalArithCompiledExpressionBoundsEstimator(StorableConstructorFlag _) : base(_) { } 55 56 private IntervalArithCompiledExpressionBoundsEstimator(IntervalArithCompiledExpressionBoundsEstimator original, Cloner cloner) : base(original, cloner) { } 99 57 100 58 public override IDeepCloneable Clone(Cloner cloner) { 101 return new IACompiledExpressionBoundsEstimator(this, cloner); 102 } 103 104 105 106 public double CheckConstraint(ISymbolicExpressionTree tree, IntervalCollection variableRanges, ShapeConstraint constraint) { 107 if (!UseIntervalSplitting) { 108 var modelBound = GetModelBound(tree, variableRanges); 109 if (constraint.Interval.Contains(modelBound)) return 0.0; 110 return Math.Abs(modelBound.LowerBound - constraint.Interval.LowerBound) + 111 Math.Abs(modelBound.UpperBound - constraint.Interval.UpperBound); 112 } 113 114 if (double.IsNegativeInfinity(constraint.Interval.LowerBound) && 115 double.IsPositiveInfinity(constraint.Interval.UpperBound)) { 116 return 0.0; 117 } 118 119 //ContainsVariableMultipleTimes(tree, out var variables); 120 121 lock (syncRoot) { EvaluatedSolutions++; } 122 123 double upperBound; 124 if (double.IsNegativeInfinity(constraint.Interval.LowerBound)) { 125 upperBound = EstimateUpperBound(tree, variableRanges.GetReadonlyDictionary(), MaxSplit, MinWidth); 126 127 return upperBound <= constraint.Interval.UpperBound 128 ? 0.0 129 : Math.Abs(upperBound - constraint.Interval.UpperBound); 130 } 131 132 double lowerBound; 133 if (double.IsPositiveInfinity(constraint.Interval.UpperBound)) { 134 lowerBound = EstimateLowerBound(tree, variableRanges.GetReadonlyDictionary(), MaxSplit, MinWidth); 135 136 return lowerBound <= constraint.Interval.LowerBound 137 ? 0.0 138 : Math.Abs(lowerBound - constraint.Interval.LowerBound); 139 } 140 141 var ranges = variableRanges.GetReadonlyDictionary(); 142 lowerBound = EstimateLowerBound(tree, ranges, MaxSplit, MinWidth); 143 upperBound = EstimateUpperBound(tree, ranges, MaxSplit, MinWidth); 144 145 var res = 0.0; 146 147 res += upperBound <= constraint.Interval.UpperBound ? 0.0 : Math.Abs(upperBound - constraint.Interval.UpperBound); 148 res += lowerBound <= constraint.Interval.LowerBound ? 0.0 : Math.Abs(lowerBound - constraint.Interval.LowerBound); 149 150 return res; 59 return new IntervalArithCompiledExpressionBoundsEstimator(this, cloner); 60 } 61 62 public double GetConstraintViolation(ISymbolicExpressionTree tree, IntervalCollection variableRanges, ShapeConstraint constraint) { 63 var modelBound = GetModelBound(tree, variableRanges); 64 if (constraint.Interval.Contains(modelBound)) return 0.0; 65 return Math.Abs(modelBound.LowerBound - constraint.Interval.LowerBound) + 66 Math.Abs(modelBound.UpperBound - constraint.Interval.UpperBound); 151 67 } 152 68 … … 157 73 public Interval GetModelBound(ISymbolicExpressionTree tree, IntervalCollection variableRanges) { 158 74 lock (syncRoot) { EvaluatedSolutions++; } 159 var resultInterval = UseIntervalSplitting 160 ? EstimateBounds(tree, variableRanges.GetReadonlyDictionary(), MaxSplit, MinWidth) 161 : EstimateBounds(tree, variableRanges.GetReadonlyDictionary()); 75 var resultInterval = EstimateBounds(tree, variableRanges.GetReadonlyDictionary()); 162 76 163 77 if (resultInterval.IsInfiniteOrUndefined || resultInterval.LowerBound <= resultInterval.UpperBound) … … 298 212 } 299 213 } 300 Array.Resize <Interval>(ref inputIntervals, count);214 Array.Resize(ref inputIntervals, count); 301 215 return variableIndices; 302 216 } … … 309 223 } 310 224 311 public static Interval EstimateBounds(ISymbolicExpressionTree tree, IReadOnlyDictionary<string, Interval> variableRanges , int n = 0, double w = 1e-5) {225 public static Interval EstimateBounds(ISymbolicExpressionTree tree, IReadOnlyDictionary<string, Interval> variableRanges) { 312 226 var variableIndices = GetVariableIndices(tree, variableRanges, out Interval[] x); 313 227 var f = Compile(tree, variableRanges, variableIndices); 314 if (n == 0) return f(x); 315 var inf = EstimateBound(x, f, true, n, w); 316 var sup = EstimateBound(x, f, false, n, w); 317 return inf < sup ? new Interval(inf, sup) : new Interval(sup, inf); 318 } 319 public double EstimateLowerBound(ISymbolicExpressionTree tree, IReadOnlyDictionary<string, Interval> variableRanges, int n = 1000, double w = 1e-5) { 320 var variableIndices = GetVariableIndices(tree, variableRanges, out Interval[] x); 321 var f = Compile(tree, variableRanges, variableIndices); 322 var inf = EstimateBound(x, f, true, n, w); 323 return inf; 324 } 325 326 public double EstimateUpperBound(ISymbolicExpressionTree tree, IReadOnlyDictionary<string, Interval> variableRanges, int n = 1000, double w = 1e-5) { 327 var variableIndices = GetVariableIndices(tree, variableRanges, out Interval[] x); 328 var f = Compile(tree, variableRanges, variableIndices); 329 var sup = EstimateBound(x, f, false, n, w); 330 return sup; 331 } 332 333 static double EstimateBound(Interval[] x, Func<Interval[], Interval> f, bool m = false, int n = 1000, double w = 1e-4) { 334 double getBound(Interval iv) => m ? iv.LowerBound : -iv.UpperBound; 335 double getVolume(Interval[] box) => box.Aggregate(1.0, (acc, iv) => acc * iv.Width); 336 337 var splits = Enumerable.Range(0, x.Length).Select(_ => new List<Interval>()).ToArray(); 338 var newbox = new Interval[x.Length]; 339 340 int compare(Tuple<double, double, Interval[]> a, Tuple<double, double, Interval[]> b) { 341 var res = a.Item1.CompareTo(b.Item1); 342 if (res == 0) { 343 res = b.Item2.CompareTo(a.Item2); 344 } 345 return res; 346 } 347 348 var q = new SortedSet<Tuple<double, double, Interval[]>>(Comparer<Tuple<double, double, Interval[]>>.Create(compare)) { 349 Tuple.Create(getBound(f(x)), getVolume(x), x) 350 }; 351 352 353 var bestBound = double.MaxValue; 354 355 // examine all the ordered pairs in the cartesian product 356 void next_pair(int i) { 357 if (i == splits.Length) { 358 var tmp = newbox.ToArray(); // make a copy to put in the queue 359 q.Add(Tuple.Create(getBound(f(tmp)), getVolume(tmp), tmp)); 360 return; 361 } 362 363 foreach (var iv in splits[i]) { 364 newbox[i] = iv; 365 next_pair(i + 1); 366 } 367 } 368 369 while (q.Count > 0 && n-- > 0) { 370 var currentBound = q.Min; q.Remove(currentBound); 371 var bound = currentBound.Item1; 372 var box = currentBound.Item3; 373 374 if (!box.Any(b => b.Width > w)) { 375 bestBound = Math.Min(bestBound, bound); 376 continue; 377 } 378 379 // do the splits 380 for (int i = 0; i < box.Length; ++i) { 381 splits[i].Clear(); 382 var iv = box[i]; 383 if (iv.Width > w) { 384 var t = iv.Split(); 385 splits[i].Add(t.Item1); 386 splits[i].Add(t.Item2); 387 } else { 388 splits[i].Add(iv); 389 } 390 } 391 next_pair(0); 392 } 393 if (q.Count > 0) { 394 bestBound = Math.Min(bestBound, q.First().Item1); 395 } 396 return m ? bestBound : -bestBound; 228 return f(x); 397 229 } 398 230 #endregion -
branches/3073_IA_constraint_splitting_reintegration/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/IntervalUtil.cs
r17887 r17891 6 6 namespace HeuristicLab.Problems.DataAnalysis.Symbolic { 7 7 public static class IntervalUtil { 8 public static double IntervalConstraintViolation(9 ShapeConstraint constraint, IBoundsEstimator estimator, IntervalCollection intervalCollection,8 public static IEnumerable<double> GetConstraintViolations( 9 IEnumerable<ShapeConstraint> constraints, IBoundsEstimator estimator, IntervalCollection intervalCollection, 10 10 ISymbolicExpressionTree solution) { 11 var variableRanges = intervalCollection.GetReadonlyDictionary(); 11 return constraints.Select(constraint => GetConstraintViolation(constraint, estimator, intervalCollection, solution)).ToList(); 12 } 12 13 13 if (constraint.Variable != null && !variableRanges.ContainsKey(constraint.Variable)) { 14 public static double GetConstraintViolation( 15 ShapeConstraint constraint, IBoundsEstimator estimator, IntervalCollection variableRanges, 16 ISymbolicExpressionTree tree) { 17 var varRanges = variableRanges.GetReadonlyDictionary(); 18 19 if (constraint.Variable != null && !varRanges.ContainsKey(constraint.Variable)) { 14 20 throw new ArgumentException( 15 21 $"The given variable {constraint.Variable} in the constraint does not exist in the model.", 16 nameof( ShapeConstraintsParser));22 nameof(constraint)); 17 23 } 18 24 19 // Create new variable ranges for defined regions25 // Create new variable ranges for defined regions 20 26 var regionRanges = new IntervalCollection(); 21 foreach (var kvp in var iableRanges) {22 if ( kvp.Key != constraint.Target &&constraint.Regions.GetReadonlyDictionary().TryGetValue(kvp.Key, out var val)) {27 foreach (var kvp in varRanges) { 28 if (constraint.Regions.GetReadonlyDictionary().TryGetValue(kvp.Key, out var val)) { 23 29 regionRanges.AddInterval(kvp.Key, val); 24 30 } else { … … 27 33 } 28 34 29 var error = 0.0;30 35 if (!constraint.IsDerivative) { 31 error = estimator.CheckConstraint(solution, regionRanges, constraint);36 return estimator.GetConstraintViolation(tree, regionRanges, constraint); 32 37 } else { 33 var tree = solution;34 38 for (var i = 0; i < constraint.NumberOfDerivations; ++i) { 35 39 if (!estimator.IsCompatible(tree) || !DerivativeCalculator.IsCompatible(tree)) { 36 throw new ArgumentException(" Cube, Root, Power symbols are not supported.");40 throw new ArgumentException("The tree contains an unsupported symbol."); 37 41 } 38 42 … … 40 44 } 41 45 42 error = estimator.CheckConstraint(tree, regionRanges, constraint);46 return estimator.GetConstraintViolation(tree, regionRanges, constraint); 43 47 } 44 45 return error;46 48 } 47 49 48 public static IEnumerable<double> IntervalConstraintsViolation(49 IEnumerable<ShapeConstraint> constraints, IBoundsEstimator estimator, IntervalCollection intervalCollection,50 ISymbolicExpressionTree solution) {51 return constraints.Select(constraint => IntervalConstraintViolation(constraint, estimator, intervalCollection, solution)).ToList();52 }53 50 } 54 51 } -
branches/3073_IA_constraint_splitting_reintegration/HeuristicLab.Problems.DataAnalysis.Views/3.4/HeuristicLab.Problems.DataAnalysis.Views-3.4.csproj
r17607 r17891 330 330 </Compile> 331 331 <Compile Include="Plugin.cs" /> 332 <Compile Include="ProblemDataConstraintView.cs">333 <SubType>UserControl</SubType>334 </Compile>335 <Compile Include="ProblemDataConstraintView.Designer.cs">336 <DependentUpon>ProblemDataConstraintView.cs</DependentUpon>337 </Compile>338 332 <Compile Include="ProblemDataView.cs"> 339 333 <SubType>UserControl</SubType> … … 443 437 <Compile Include="Regression\RegressionSolutionScatterPlotView.Designer.cs"> 444 438 <DependentUpon>RegressionSolutionScatterPlotView.cs</DependentUpon> 439 </Compile> 440 <Compile Include="ShapeConstraintsView.cs"> 441 <SubType>UserControl</SubType> 442 </Compile> 443 <Compile Include="ShapeConstraintsView.Designer.cs"> 444 <DependentUpon>ShapeConstraintsView.cs</DependentUpon> 445 445 </Compile> 446 446 <Compile Include="Solution Views\ClassificationSolutionView.cs"> -
branches/3073_IA_constraint_splitting_reintegration/HeuristicLab.Problems.DataAnalysis.Views/3.4/IntervalConstraintView.Designer.cs
r17607 r17891 36 36 this.label1 = new System.Windows.Forms.Label(); 37 37 this.numberderivationInput = new System.Windows.Forms.ComboBox(); 38 this.ischeckedCheckBox = new System.Windows.Forms.CheckBox();39 this.expressionInput = new System.Windows.Forms.TextBox();40 this.expressionLabel = new System.Windows.Forms.Label();41 38 this.errorProvider = new System.Windows.Forms.ErrorProvider(this.components); 42 39 this.groupBox1.SuspendLayout(); … … 116 113 this.groupBox1.Controls.Add(this.label1); 117 114 this.groupBox1.Controls.Add(this.numberderivationInput); 118 this.groupBox1.Controls.Add(this.ischeckedCheckBox);119 this.groupBox1.Controls.Add(this.expressionInput);120 this.groupBox1.Controls.Add(this.expressionLabel);121 115 this.groupBox1.Controls.Add(this.variableInput); 122 116 this.groupBox1.Controls.Add(this.lowerboundInput); … … 162 156 this.numberderivationInput.TabIndex = 27; 163 157 this.numberderivationInput.SelectedIndexChanged += new System.EventHandler(this.numberderivationInput_SelectedIndexChanged); 164 // 165 // ischeckedCheckBox 166 // 167 this.ischeckedCheckBox.AutoSize = true; 168 this.ischeckedCheckBox.Location = new System.Drawing.Point(108, 154); 169 this.ischeckedCheckBox.Name = "ischeckedCheckBox"; 170 this.ischeckedCheckBox.Size = new System.Drawing.Size(18, 17); 171 this.ischeckedCheckBox.TabIndex = 26; 172 this.ischeckedCheckBox.UseVisualStyleBackColor = true; 173 this.ischeckedCheckBox.CheckedChanged += new System.EventHandler(this.ischeckedCheckBox_CheckedChanged); 174 // 175 // expressionInput 176 // 177 this.expressionInput.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 178 | System.Windows.Forms.AnchorStyles.Right))); 179 this.expressionInput.Location = new System.Drawing.Point(108, 19); 180 this.expressionInput.Name = "expressionInput"; 181 this.expressionInput.Size = new System.Drawing.Size(473, 22); 182 this.expressionInput.TabIndex = 25; 183 // 184 // expressionLabel 185 // 186 this.expressionLabel.AutoSize = true; 187 this.expressionLabel.Location = new System.Drawing.Point(8, 22); 188 this.expressionLabel.Name = "expressionLabel"; 189 this.expressionLabel.Size = new System.Drawing.Size(81, 17); 190 this.expressionLabel.TabIndex = 24; 191 this.expressionLabel.Text = "Expression:"; 158 192 159 // 193 160 // errorProvider … … 218 185 private System.Windows.Forms.TextBox variableInput; 219 186 private System.Windows.Forms.GroupBox groupBox1; 220 private System.Windows.Forms.TextBox expressionInput;221 private System.Windows.Forms.Label expressionLabel;222 187 private System.Windows.Forms.ErrorProvider errorProvider; 223 private System.Windows.Forms.CheckBox ischeckedCheckBox;224 188 private System.Windows.Forms.ComboBox numberderivationInput; 225 189 private System.Windows.Forms.Label label1; -
branches/3073_IA_constraint_splitting_reintegration/HeuristicLab.Problems.DataAnalysis.Views/3.4/IntervalConstraintView.cs
r17887 r17891 33 33 public sealed partial class IntervalConstraintView : ItemView { 34 34 public new ShapeConstraint Content { 35 get => (ShapeConstraint) 35 get => (ShapeConstraint)base.Content; 36 36 set => base.Content = value; 37 37 } … … 39 39 public IntervalConstraintView() { 40 40 InitializeComponent(); 41 int[] items = {1, 2, 3}; 42 expressionInput.ReadOnly = true; 41 int[] items = { 1, 2, 3 }; 43 42 numberderivationInput.DataSource = items; 44 43 } … … 61 60 protected override void SetEnabledStateOfControls() { 62 61 base.SetEnabledStateOfControls(); 63 expressionInput.Enabled = Content != null && !Locked && !ReadOnly; 64 variableInput.Enabled = Content != null && !Locked && !ReadOnly; 62 variableInput.Enabled = Content != null && !Locked && !ReadOnly; 65 63 numberderivationInput.Enabled = Content != null && !Locked && !ReadOnly; 66 lowerboundInput.Enabled = Content != null && !Locked && !ReadOnly; 67 upperboundInput.Enabled = Content != null && !Locked && !ReadOnly; 68 ischeckedCheckBox.Enabled = Content != null && !Locked && !ReadOnly; 64 lowerboundInput.Enabled = Content != null && !Locked && !ReadOnly; 65 upperboundInput.Enabled = Content != null && !Locked && !ReadOnly; 69 66 } 70 67 … … 83 80 return double.NegativeInfinity; 84 81 default: { 85 if (double.TryParse(input, out var value)) { 86 return value; 82 if (double.TryParse(input, out var value)) { 83 return value; 84 } 85 86 errorProvider.SetError(control, "Invalid input: value must be a double."); 87 return double.NaN; 87 88 } 88 89 errorProvider.SetError(control, "Invalid Input: Value must be a double!");90 return double.NaN;91 }92 89 } 93 90 } … … 95 92 private void UpdateControls() { 96 93 if (Content == null) { 97 expressionInput.Text = string.Empty;98 94 lowerboundInput.Text = string.Empty; 99 95 upperboundInput.Text = string.Empty; … … 101 97 } 102 98 103 expressionInput.Text = Content.Expression;104 99 lowerboundInput.Text = Content.Interval.LowerBound.ToString(); 105 100 upperboundInput.Text = Content.Interval.UpperBound.ToString(); … … 107 102 variableInput.Text = Content.Variable; 108 103 if (!Content.IsDerivative) { 109 numberderivationInput.Enabled 104 numberderivationInput.Enabled = false; 110 105 numberderivationInput.SelectedItem = null; 111 numberderivationInput.Text = "0"; 112 } 113 else { 114 numberderivationLabel.Visible = true; 115 numberderivationInput.Visible = true; 116 numberderivationInput.Enabled = true; 106 numberderivationInput.Text = "0"; 107 } else { 108 numberderivationLabel.Visible = true; 109 numberderivationInput.Visible = true; 110 numberderivationInput.Enabled = true; 117 111 numberderivationInput.SelectedItem = Content.NumberOfDerivations; 118 112 } 119 120 ischeckedCheckBox.Checked = Content.Enabled;121 113 } 122 114 … … 128 120 var value = ParseDoubleValue(lowerboundInput.Text, lowerboundInput, errorProvider); 129 121 if (double.IsNaN(value)) { 130 errorProvider.SetError(lowerboundInput, "Invalid Input: Lowerbound must be a double value!");122 errorProvider.SetError(lowerboundInput, "Invalid input: lower bound must be a double value."); 131 123 e.Cancel = true; 132 124 return; … … 134 126 135 127 if (value > Content.Interval.UpperBound) { 136 errorProvider.SetError(lowerboundInput, "Invalid Input: Lowerbound must be smaller than Upperbound!");128 errorProvider.SetError(lowerboundInput, "Invalid input: lower bound must be smaller than upper bound."); 137 129 e.Cancel = true; 138 130 return; … … 152 144 var value = ParseDoubleValue(upperboundInput.Text, upperboundInput, errorProvider); 153 145 if (double.IsNaN(value)) { 154 errorProvider.SetError(upperboundInput, "Invalid Input: Upperbound must be a double value!");146 errorProvider.SetError(upperboundInput, "Invalid Input: upper bound must be a double value."); 155 147 e.Cancel = true; 156 148 return; … … 158 150 159 151 if (value < Content.Interval.LowerBound) { 160 errorProvider.SetError(upperboundInput, "Invalid Input: Upperbound must be bigger than Lowerbound!");152 errorProvider.SetError(upperboundInput, "Invalid input: upper bound must be bigger than lower bound."); 161 153 e.Cancel = true; 162 154 return; … … 173 165 } 174 166 175 private void ischeckedCheckBox_CheckedChanged(object sender, EventArgs e) {176 Content.Enabled = ischeckedCheckBox.Checked;177 }178 179 167 private void numberderivationInput_SelectedIndexChanged(object sender, EventArgs e) { 180 168 if (numberderivationInput.SelectedItem == null) { 181 Content.NumberOfDerivations 169 Content.NumberOfDerivations = 0; 182 170 numberderivationInput.Enabled = false; 183 171 return; 184 172 } 185 173 186 if ((int) 174 if ((int)numberderivationInput.SelectedItem == 1) 187 175 Content.NumberOfDerivations = 1; 188 else if ((int) 176 else if ((int)numberderivationInput.SelectedItem == 2) 189 177 Content.NumberOfDerivations = 2; 190 else if ((int) 178 else if ((int)numberderivationInput.SelectedItem == 3) 191 179 Content.NumberOfDerivations = 3; 192 180 } -
branches/3073_IA_constraint_splitting_reintegration/HeuristicLab.Problems.DataAnalysis.Views/3.4/ShapeConstraintsView.Designer.cs
r17890 r17891 27 27 28 28 namespace HeuristicLab.Problems.DataAnalysis.Views { 29 partial class ProblemDataConstraintView {29 partial class ShapeConstraintsView { 30 30 /// <summary> 31 31 /// Required designer variable. … … 38 38 /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> 39 39 protected override void Dispose(bool disposing) { 40 41 42 43 40 if (disposing && (components != null)) { 41 components.Dispose(); 42 } 43 base.Dispose(disposing); 44 44 } 45 45 … … 51 51 /// </summary> 52 52 private void InitializeComponent() { 53 System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof( ProblemDataConstraintView));53 System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ShapeConstraintsView)); 54 54 this.splitContainer1 = new System.Windows.Forms.SplitContainer(); 55 55 this.groupBox1 = new System.Windows.Forms.GroupBox(); … … 179 179 #endregion 180 180 181 private System.Windows.Forms.SplitContainer 182 private System.Windows.Forms.GroupBox 183 private System.Windows.Forms.Button 184 private System.Windows.Forms.Label 181 private System.Windows.Forms.SplitContainer splitContainer1; 182 private System.Windows.Forms.GroupBox groupBox1; 183 private System.Windows.Forms.Button parseBtn; 184 private System.Windows.Forms.Label label1; 185 185 private HeuristicLab.Core.Views.CheckedItemListView<ShapeConstraint> intervalConstraintsView; 186 private System.Windows.Forms.TextBox 187 private Label 188 186 private System.Windows.Forms.TextBox constraintsInput; 187 private Label errorOutput; 188 } 189 189 } -
branches/3073_IA_constraint_splitting_reintegration/HeuristicLab.Problems.DataAnalysis.Views/3.4/ShapeConstraintsView.cs
r17890 r17891 23 23 24 24 using System; 25 using System.Collections.Generic;26 25 using System.Drawing; 26 using System.Text; 27 27 using HeuristicLab.Collections; 28 using HeuristicLab.Core;29 28 using HeuristicLab.MainForm; 30 29 using HeuristicLab.MainForm.WindowsForms; 31 30 32 31 namespace HeuristicLab.Problems.DataAnalysis.Views { 33 [View(" ParsedConstraintView")]32 [View("ShapeConstraints View")] 34 33 [Content(typeof(ShapeConstraints), true)] 35 public partial class ProblemDataConstraintView : AsynchronousContentView {34 public partial class ShapeConstraintsView : AsynchronousContentView { 36 35 public new ShapeConstraints Content { 37 36 get => (ShapeConstraints)base.Content; … … 39 38 } 40 39 41 public ProblemDataConstraintView() { 40 public bool suspendUpdates = false; 41 42 public ShapeConstraintsView() { 42 43 InitializeComponent(); 43 44 errorOutput.Text = ""; … … 46 47 protected override void OnContentChanged() { 47 48 base.OnContentChanged(); 49 this.intervalConstraintsView.Content = Content; 48 50 UpdateControl(); 49 51 } … … 51 53 protected override void RegisterContentEvents() { 52 54 base.RegisterContentEvents(); 53 Content.ItemsAdded += constraints_ Updated;54 Content.ItemsRemoved += constraint_ removed;55 Content.ItemsAdded += constraints_Added; 56 Content.ItemsRemoved += constraint_Removed; 55 57 Content.Changed += Content_Changed; 58 Content.CollectionReset += constraints_Reset; 59 Content.ItemsMoved += constraints_Moved; 60 Content.ItemsReplaced += Content_ItemsReplaced; 61 Content.CheckedItemsChanged += Content_CheckedItemsChanged; 56 62 } 57 63 64 58 65 protected override void DeregisterContentEvents() { 59 Content.ItemsAdded -= constraints_ Updated;60 Content.ItemsRemoved -= constraint_ removed;66 Content.ItemsAdded -= constraints_Added; 67 Content.ItemsRemoved -= constraint_Removed; 61 68 Content.Changed -= Content_Changed; 69 Content.CollectionReset -= constraints_Reset; 70 Content.ItemsMoved -= constraints_Moved; 71 Content.ItemsReplaced -= Content_ItemsReplaced; 72 Content.CheckedItemsChanged -= Content_CheckedItemsChanged; 62 73 base.DeregisterContentEvents(); 63 74 } … … 68 79 69 80 70 71 81 private void parseBtn_Click(object sender, EventArgs e) { 72 82 if (constraintsInput.Text != null) { 73 intervalConstraints.Clear(); 83 suspendUpdates = true; 84 Content.Clear(); 74 85 try { 75 86 var parsedConstraints = ShapeConstraintsParser.ParseConstraints(constraintsInput.Text); 76 Content.Clear(); 77 Content.AddRange(parsedConstraints); 78 InfoText = "Constraints successfully parsed."; 79 InfoColor = Color.DarkGreen; 87 Content = parsedConstraints; 88 errorOutput.Text = "Constraints successfully parsed."; 89 errorOutput.ForeColor = Color.DarkGreen; 80 90 //Catch the exception from the constraints parser and show it in the error dialog 81 91 } catch (ArgumentException ex) { 82 92 Content.Clear(); 83 InfoText = ex.Message.Replace("Parameter name", "@Line");84 InfoColor = Color.DarkRed;93 errorOutput.Text = ex.Message.Replace("Parameter name", "@Line"); 94 errorOutput.ForeColor = Color.DarkRed; 85 95 } 96 suspendUpdates = false; 97 UpdateControl(); 86 98 } else { 87 99 errorOutput.Text = "No constraints were found!"; … … 90 102 91 103 private void UpdateControl() { 104 if (suspendUpdates) return; 92 105 if (Content == null) { 93 intervalConstraints.Clear(); 94 intervalConstraintsView.Content = intervalConstraints; 106 constraintsInput.Text = string.Empty; 95 107 } else { 96 intervalConstraints.Clear(); 97 constraintsInput.Text = Content.Input; 98 errorOutput.ForeColor = InfoColor; 99 errorOutput.Text = InfoText; 100 foreach (var constraint in Content) intervalConstraints.Add(constraint, constraint.Enabled); 101 102 intervalConstraintsView.Content = intervalConstraints; 108 constraintsInput.Text = ToString(Content); 103 109 } 104 110 } 105 111 106 private void constraint_Changed(object sender, EventArgs e) { 107 var constraint = (ShapeConstraint)sender; 108 intervalConstraints.SetItemCheckedState(constraint, constraint.Enabled); 112 private string ToString(ShapeConstraints constraints) { 113 var sb = new StringBuilder(); 114 foreach (var constraint in constraints) { 115 if (!constraints.ItemChecked(constraint)) { 116 sb.Append("# ").AppendLine(constraint.ToString()); 117 } else { 118 sb.AppendLine(constraint.ToString()); 119 } 120 } 121 return sb.ToString(); 109 122 } 110 123 111 private void constraints_Updated(object sender, 124 private void constraint_Changed(object sender, EventArgs e) { 125 UpdateControl(); 126 } 127 128 private void constraints_Added(object sender, 112 129 CollectionItemsChangedEventArgs<IndexedItem<ShapeConstraint>> e) { 113 130 foreach (var addedItem in e.Items) addedItem.Value.Changed += constraint_Changed; 131 UpdateControl(); 114 132 } 115 133 116 private void constraint_ removed(object sender, CollectionItemsChangedEventArgs<IndexedItem<ShapeConstraint>> e) {134 private void constraint_Removed(object sender, CollectionItemsChangedEventArgs<IndexedItem<ShapeConstraint>> e) { 117 135 foreach (var removedItem in e.Items) removedItem.Value.Changed -= constraint_Changed; 136 UpdateControl(); 118 137 } 119 138 120 private void constraint_CheckedItemChanged(object sender, 121 CollectionItemsChangedEventArgs<IndexedItem<ShapeConstraint>> e) { 122 ICheckedItemList<ShapeConstraint> checkedItemList = (ICheckedItemList<ShapeConstraint>)sender; 123 foreach (var indexedItem in e.Items) indexedItem.Value.Enabled = checkedItemList.ItemChecked(indexedItem.Value); 139 private void constraints_Moved(object sender, CollectionItemsChangedEventArgs<IndexedItem<ShapeConstraint>> e) { 140 UpdateControl(); 141 } 142 143 private void constraints_Reset(object sender, CollectionItemsChangedEventArgs<IndexedItem<ShapeConstraint>> e) { 144 foreach (var addedItem in e.Items) addedItem.Value.Changed += constraint_Changed; 145 foreach (var removedItem in e.OldItems) removedItem.Value.Changed -= constraint_Changed; 146 UpdateControl(); 147 } 148 149 private void Content_CheckedItemsChanged(object sender, CollectionItemsChangedEventArgs<IndexedItem<ShapeConstraint>> e) { 150 UpdateControl(); 151 } 152 153 private void Content_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<IndexedItem<ShapeConstraint>> e) { 154 foreach (var addedItem in e.Items) addedItem.Value.Changed += constraint_Changed; 155 foreach (var removedItem in e.OldItems) removedItem.Value.Changed -= constraint_Changed; 156 UpdateControl(); 124 157 } 125 158 126 159 private void constraintsInput_TextChanged(object sender, EventArgs e) { 127 if (Content.Input != constraintsInput.Text) { 128 Content.Input = constraintsInput.Text; 129 Content.InfoText = "Unparsed changes! Press parse button to save changes."; 130 Content.InfoColor = Color.DarkOrange; 131 } else { 132 errorOutput.Text = ""; 133 } 160 errorOutput.Text = "Unparsed changes! Press parse button to save changes."; 161 errorOutput.ForeColor = Color.DarkOrange; 134 162 } 135 163 -
branches/3073_IA_constraint_splitting_reintegration/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Interval/ShapeConstraint.cs
r17887 r17891 102 102 } 103 103 104 [Storable]105 private bool enabled;106 107 public bool Enabled {108 get => enabled;109 set {110 if (enabled == value)111 return;112 enabled = value;113 OnChanged();114 }115 }104 // [Storable] 105 // private bool enabled; 106 // 107 // public bool Enabled { 108 // get => enabled; 109 // set { 110 // if (enabled == value) 111 // return; 112 // enabled = value; 113 // OnChanged(); 114 // } 115 // } 116 116 117 117 [Storable] … … 143 143 144 144 // without derivation 145 public ShapeConstraint(Interval interval, double weight , bool enabled)145 public ShapeConstraint(Interval interval, double weight) 146 146 : this(string.Empty, 0, 147 interval, new IntervalCollection(), weight , enabled) { }148 149 public ShapeConstraint(Interval interval, IntervalCollection regions, double weight , bool enabled)147 interval, new IntervalCollection(), weight) { } 148 149 public ShapeConstraint(Interval interval, IntervalCollection regions, double weight) 150 150 : this(string.Empty, 0, 151 interval, regions, weight , enabled) { }151 interval, regions, weight) { } 152 152 153 153 public ShapeConstraint(string variable, int numberOfDerivations, 154 Interval interval, double weight , bool enabled)154 Interval interval, double weight) 155 155 : this(variable, numberOfDerivations, 156 interval, new IntervalCollection(), weight , enabled) { }156 interval, new IntervalCollection(), weight) { } 157 157 158 158 public ShapeConstraint(string variable, int numberOfDerivations, 159 Interval interval, IntervalCollection regions, double weight , bool enabled) {159 Interval interval, IntervalCollection regions, double weight) { 160 160 this.regions = regions; 161 161 this.weight = weight; … … 163 163 this.numberOfDerivations = numberOfDerivations; 164 164 this.interval = interval; 165 this.enabled = enabled;165 //this.enabled = enabled; 166 166 } 167 167 … … 176 176 NumberOfDerivations = original.NumberOfDerivations; 177 177 Interval = original.Interval; 178 Enabled = original.Enabled;178 //Enabled = original.Enabled; 179 179 } 180 180 … … 208 208 if (Regions != null) { 209 209 foreach (var region in Regions.GetReadonlyDictionary()) 210 expression += $", {region.Key}=({region.Value.LowerBound} .. {region.Value.UpperBound})"; 210 expression += $", {region.Key} in [{region.Value.LowerBound} .. {region.Value.UpperBound}]"; 211 } 212 if (Weight != 1.0) { 213 expression += $" weight: {weight}"; 211 214 } 212 215 … … 226 229 if (Regions != null) { 227 230 foreach (var region in Regions.GetReadonlyDictionary()) 228 expression += $", {region.Key}=({region.Value.LowerBound} .. {region.Value.UpperBound})"; 231 expression += $", {region.Key} in [{region.Value.LowerBound} .. {region.Value.UpperBound}]"; 232 } 233 if(Weight != 1.0) { 234 expression += $" weight: {weight}"; 229 235 } 230 236 return expression; -
branches/3073_IA_constraint_splitting_reintegration/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Interval/ShapeConstraintsParser.cs
r17887 r17891 30 30 namespace HeuristicLab.Problems.DataAnalysis { 31 31 public static class ShapeConstraintsParser { 32 public static IEnumerable<ShapeConstraint> ParseConstraints(string text, IEnumerable<string> variables) {32 public static ShapeConstraints ParseConstraints(string text) { 33 33 if (string.IsNullOrEmpty(text)) throw new ArgumentNullException(nameof(text)); 34 if (variables == null) throw new ArgumentNullException(nameof(variables));35 if (!variables.Any()) throw new ArgumentException("Variables are empty.", nameof(variables));36 34 37 35 var lines = text.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None); 38 36 37 var sc = new ShapeConstraints(); 39 38 foreach (var line in lines) { 40 39 var trimmedLine = line.Trim(); 41 if (trimmedLine == "") continue; //If it is a comment just continue without saving anything40 if (trimmedLine == "") continue; // If it is a comment just continue without saving anything 42 41 if (trimmedLine.StartsWith("#")) { 43 42 // disabled constraints are commented 44 var constraint = ParseConstaint(trimmedLine.TrimStart('#', ' ') , variables);45 constraint.Enabled = false;46 yield return constraint;43 var constraint = ParseConstaint(trimmedLine.TrimStart('#', ' ')); 44 sc.Add(constraint); 45 sc.SetItemCheckedState(constraint, false); 47 46 } else { 48 yield return ParseConstaint(trimmedLine, variables); 47 var constraint = ParseConstaint(trimmedLine); 48 sc.Add(constraint); 49 sc.SetItemCheckedState(constraint, true); 49 50 } 50 51 } 51 } 52 53 public static ShapeConstraint ParseConstaint(string expr, IEnumerable<string> variables) { 52 return sc; 53 } 54 55 public static ShapeConstraint ParseConstaint(string expr) { 54 56 var trimmedLine = expr.TrimStart(); 55 57 if (trimmedLine.StartsWith("f")) { 56 58 return ParseFunctionRangeConstraint(expr); 57 59 } else if (trimmedLine.StartsWith("d") || trimmedLine.StartsWith("∂")) { 58 return ParseDerivationConstraint(expr , variables);60 return ParseDerivationConstraint(expr); 59 61 } else { 60 62 throw new … … 125 127 throw new ArgumentException("A constraint cannot contain multiple regions of the same variable."); 126 128 } 127 return new ShapeConstraint(interval, regions, weight , enabled: true);129 return new ShapeConstraint(interval, regions, weight); 128 130 } else 129 return new ShapeConstraint(interval, weight , enabled: true);131 return new ShapeConstraint(interval, weight); 130 132 } else 131 133 throw new ArgumentException("The inserted target constraint is not valid.", nameof(expr)); 132 134 } 133 public static ShapeConstraint ParseDerivationConstraint(string expr , IEnumerable<string> variables) {135 public static ShapeConstraint ParseDerivationConstraint(string expr) { 134 136 var match = Regex.Match(expr, 135 137 @"([d∂])" + … … 155 157 var derivationVariable = match.Groups["varName"].Captures[0].Value.Trim(); 156 158 157 if (variables.All(v => v != derivationVariable))158 throw new ArgumentException($"The given variable {derivationVariable} does not exist in the dataset.",159 nameof(expr));160 161 159 var enumeratorNumDeriv = match.Groups["numDerivations"].Captures[0].Value.Trim(); 162 160 var denominatorNumDeriv = match.Groups["numDerivations"].Captures[1].Value.Trim(); … … 191 189 throw new ArgumentException("A constraint cannot contain multiple regions of the same variable."); 192 190 } 193 return new ShapeConstraint(variable, numberOfDerivation, interval, regions, weight , enabled: true);191 return new ShapeConstraint(variable, numberOfDerivation, interval, regions, weight); 194 192 } else 195 return new ShapeConstraint(variable, numberOfDerivation, interval, weight , enabled: true);193 return new ShapeConstraint(variable, numberOfDerivation, interval, weight); 196 194 } else 197 195 throw new ArgumentException("The inserted derivation constraint is not valid.", nameof(expr)); -
branches/3073_IA_constraint_splitting_reintegration/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionProblemData.cs
r17887 r17891 35 35 protected const string TargetVariableParameterName = "TargetVariable"; 36 36 protected const string VariableRangesParameterName = "VariableRanges"; 37 protected const string IntervalConstraintsParameterName = "IntervalConstraints";37 protected const string ShapeConstraintsParameterName = "ShapeConstraints"; 38 38 public string Filename { get; set; } 39 39 … … 94 94 problemData.Parameters.Add(new ConstrainedValueParameter<StringValue>(TargetVariableParameterName, new ItemSet<StringValue>())); 95 95 problemData.Parameters.Add(new FixedValueParameter<IntervalCollection>(VariableRangesParameterName, "", new IntervalCollection())); 96 problemData.Parameters.Add(new FixedValueParameter<ShapeConstraints>( IntervalConstraintsParameterName, "", new ShapeConstraints()));96 problemData.Parameters.Add(new FixedValueParameter<ShapeConstraints>(ShapeConstraintsParameterName, "", new ShapeConstraints())); 97 97 emptyProblemData = problemData; 98 98 } … … 109 109 } 110 110 111 public IFixedValueParameter<ShapeConstraints> IntervalConstraintsParameter =>112 (IFixedValueParameter<ShapeConstraints>) Parameters[ IntervalConstraintsParameterName];113 114 public ShapeConstraints IntervalConstraints => IntervalConstraintsParameter.Value;111 public IFixedValueParameter<ShapeConstraints> ShapeConstraintsParameter => 112 (IFixedValueParameter<ShapeConstraints>) Parameters[ShapeConstraintsParameterName]; 113 114 public ShapeConstraints ShapeConstraints => ShapeConstraintsParameter.Value; 115 115 116 116 … … 146 146 Parameters.Add(new FixedValueParameter<IntervalCollection>(VariableRangesParameterName, intervalCollection)); 147 147 } 148 149 if (!Parameters.ContainsKey(IntervalConstraintsParameterName)) { 150 Parameters.Add(new FixedValueParameter<ShapeConstraints>(IntervalConstraintsParameterName, new ShapeConstraints())); 151 } 148 if(Parameters.ContainsKey("IntervalConstraints")) { 149 var param = (IFixedValueParameter<ShapeConstraints>)Parameters["IntervalConstraints"]; 150 Parameters.Remove(param); 151 Parameters.Add(new FixedValueParameter<ShapeConstraints>(ShapeConstraintsParameterName, param.Value)); 152 } 153 if (!Parameters.ContainsKey(ShapeConstraintsParameterName)) { 154 Parameters.Add(new FixedValueParameter<ShapeConstraints>(ShapeConstraintsParameterName, new ShapeConstraints())); 155 } 156 152 157 RegisterParameterEvents(); 153 158 } … … 176 181 IEnumerable<ITransformation> transformations = null, 177 182 IntervalCollection variableRanges = null, 178 ShapeConstraints intervalConstraints = null)183 ShapeConstraints shapeConstraints = null) 179 184 : base(dataset, allowedInputVariables, transformations ?? Enumerable.Empty<ITransformation>()) { 180 185 var variables = InputVariables.Select(x => x.AsReadOnly()).ToList(); … … 184 189 } 185 190 Parameters.Add(new FixedValueParameter<IntervalCollection>(VariableRangesParameterName, variableRanges)); 186 if ( intervalConstraints == null) {187 intervalConstraints = new ShapeConstraints();191 if (shapeConstraints == null) { 192 shapeConstraints = new ShapeConstraints(); 188 193 } 189 Parameters.Add(new FixedValueParameter<ShapeConstraints>( IntervalConstraintsParameterName, intervalConstraints));194 Parameters.Add(new FixedValueParameter<ShapeConstraints>(ShapeConstraintsParameterName, shapeConstraints)); 190 195 RegisterParameterEvents(); 191 196 } -
branches/3073_IA_constraint_splitting_reintegration/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/ShapeConstraints.cs
r17887 r17891 22 22 #endregion 23 23 using System; 24 using System.Linq; 24 25 using System.Collections.Generic; 25 using System.Drawing;26 using System.Linq;27 26 using HEAL.Attic; 28 27 using HeuristicLab.Common; 29 28 using HeuristicLab.Core; 29 using HeuristicLab.Collections; 30 30 31 31 namespace HeuristicLab.Problems.DataAnalysis { 32 32 [StorableType("A56BFB05-8F11-4766-9FBF-20C7010F1CA3")] 33 33 [Item("ShapeConstraints", "Represents shape constraints associated with a regression problem data e.g. monotonicity constraints.")] 34 public class ShapeConstraints : ItemCollection<ShapeConstraint> {34 public class ShapeConstraints : CheckedItemList<ShapeConstraint> { 35 35 // private static readonly string exampleInput = "# Example for a target variable constraint:" + Environment.NewLine + 36 36 // "f in [0 .. 100]" + Environment.NewLine + Environment.NewLine + … … 87 87 // } 88 88 89 public IEnumerable<ShapeConstraint> EnabledConstraints => base. list.Where(c => c.Enabled);89 public IEnumerable<ShapeConstraint> EnabledConstraints => base.CheckedItems.Select(checkedItem => checkedItem.Value); 90 90 91 protected override void OnItemsAdded(IEnumerable< ShapeConstraint> items) {91 protected override void OnItemsAdded(IEnumerable<IndexedItem<ShapeConstraint>> items) { 92 92 base.OnItemsAdded(items); 93 93 foreach (var item in items) 94 item. Changed += Item_Changed;94 item.Value.Changed += Item_Changed; 95 95 } 96 96 97 protected override void OnItemsRemoved(IEnumerable< ShapeConstraint> items) {97 protected override void OnItemsRemoved(IEnumerable<IndexedItem<ShapeConstraint>> items) { 98 98 base.OnItemsRemoved(items); 99 99 foreach (var item in items) 100 item. Changed -= Item_Changed;100 item.Value.Changed -= Item_Changed; 101 101 } 102 102 103 protected override void OnCollectionReset(IEnumerable<ShapeConstraint> items, IEnumerable<ShapeConstraint> oldItems) { 103 protected override void OnCollectionReset( 104 IEnumerable<IndexedItem<ShapeConstraint>> items, 105 IEnumerable<IndexedItem<ShapeConstraint>> oldItems) { 104 106 base.OnCollectionReset(items, oldItems); 105 107 foreach (var item in items) 106 item. Changed += Item_Changed;108 item.Value.Changed += Item_Changed; 107 109 foreach (var item in oldItems) 108 item. Changed -= Item_Changed;110 item.Value.Changed -= Item_Changed; 109 111 } 110 112 -
branches/3073_IA_constraint_splitting_reintegration/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Regression/IRegressionProblemData.cs
r17887 r17891 31 31 32 32 IntervalCollection VariableRanges { get; } 33 ShapeConstraints IntervalConstraints { get; }33 ShapeConstraints ShapeConstraints { get; } 34 34 35 35 IEnumerable<double> TargetVariableValues { get; }
Note: See TracChangeset
for help on using the changeset viewer.