Changeset 18213
- Timestamp:
- 02/08/22 13:06:49 (3 years ago)
- Location:
- branches/3138_Shape_Constraints_Transformations
- Files:
-
- 2 added
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/3138_Shape_Constraints_Transformations/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression-3.4.csproj
r18181 r18213 263 263 <Private>False</Private> 264 264 </ProjectReference> 265 <ProjectReference Include="..\..\HeuristicLab.Random\3.3\HeuristicLab.Random-3.3.csproj"> 266 <Project>{F4539FB6-4708-40C9-BE64-0A1390AEA197}</Project> 267 <Name>HeuristicLab.Random-3.3</Name> 268 </ProjectReference> 265 269 </ItemGroup> 266 270 <ItemGroup> -
branches/3138_Shape_Constraints_Transformations/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/ShapeConstraintsAnalyzer.cs
r17958 r18213 20 20 #endregion 21 21 22 using System.Collections; 23 using System.Collections.Generic; 22 24 using System.Linq; 23 25 using HEAL.Attic; … … 28 30 using HeuristicLab.Optimization; 29 31 using HeuristicLab.Parameters; 32 using HeuristicLab.Random; 30 33 31 34 namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Regression { … … 36 39 private const string ConstraintViolationsParameterName = "ConstraintViolations"; 37 40 private const string InfeasibleSolutionsParameterName = "InfeasibleSolutions"; 41 private const string AverageConstraintViolationsParameterName = "AverageConstraintViolations"; 42 private const string SymbolicDataAnalysisTreeInterpreterParameterName = "SymbolicExpressionTreeInterpreter"; 38 43 39 44 #region parameter properties … … 48 53 (IResultParameter<DataTable>)Parameters[InfeasibleSolutionsParameterName]; 49 54 55 public IResultParameter<DataTable> AverageConstraintViolationsParameter => 56 (IResultParameter<DataTable>)Parameters[AverageConstraintViolationsParameterName]; 57 58 public ILookupParameter<ISymbolicDataAnalysisExpressionTreeInterpreter> SymbolicDataAnalysisTreeInterpreterParameter => 59 (ILookupParameter<ISymbolicDataAnalysisExpressionTreeInterpreter>)Parameters[SymbolicDataAnalysisTreeInterpreterParameterName]; 60 50 61 #endregion 51 62 52 #region properties63 #region properties 53 64 public IRegressionProblemData RegressionProblemData => RegressionProblemDataParameter.ActualValue; 54 65 public DataTable ConstraintViolations => ConstraintViolationsParameter.ActualValue; 55 66 public DataTable InfeasibleSolutions => InfeasibleSolutionsParameter.ActualValue; 67 public DataTable AverageConstraintViolations => AverageConstraintViolationsParameter.ActualValue; 56 68 #endregion 57 69 … … 75 87 Parameters.Add(new ResultParameter<DataTable>(InfeasibleSolutionsParameterName, 76 88 "The number of infeasible solutions.")); 89 Parameters.Add(new ResultParameter<DataTable>(AverageConstraintViolationsParameterName, 90 "The average violations of each constraint.")); 91 Parameters.Add(new LookupParameter<ISymbolicDataAnalysisExpressionTreeInterpreter>(SymbolicDataAnalysisTreeInterpreterParameterName, 92 "The interpreter that should be used to calculate the output values of the symbolic data analysis tree.") { Hidden = true }); 93 77 94 78 95 … … 90 107 } 91 108 }; 109 110 AverageConstraintViolationsParameter.DefaultValue = new DataTable(SymbolicDataAnalysisTreeInterpreterParameterName) { 111 VisualProperties = { 112 XAxisTitle = "Generations", 113 YAxisTitle = "Average Constraint Violations" 114 } 115 }; 92 116 } 93 117 94 118 95 119 [StorableHook(HookType.AfterDeserialization)] 96 private void AfterDeserialization() { } 120 private void AfterDeserialization() { 121 if (!Parameters.ContainsKey(SymbolicDataAnalysisTreeInterpreterParameterName)) 122 Parameters.Add(new LookupParameter<ISymbolicDataAnalysisExpressionTreeInterpreter>(SymbolicDataAnalysisTreeInterpreterParameterName, 123 "The interpreter that should be used to calculate the output values of the symbolic data analysis tree.") { Hidden = true }); 124 } 97 125 98 126 public override IOperation Apply() { 99 127 var problemData = (IShapeConstrainedRegressionProblemData)RegressionProblemData; 100 128 var trees = SymbolicExpressionTree.ToArray(); 101 129 102 130 var results = ResultCollection; 103 var constraints = problemData.ShapeConstraints.EnabledConstraints; 131 var modelConstraints = problemData.ShapeConstraints.EnabledConstraints; 132 var extendedConstraints = problemData.CheckedExtendedConstraints; 104 133 var variableRanges = problemData.VariableRanges; 105 134 var constraintViolationsTable = ConstraintViolations; 135 var averageConstraintViolations = AverageConstraintViolations; 136 var interpreter = SymbolicDataAnalysisTreeInterpreterParameter.ActualValue; 106 137 var estimator = new IntervalArithBoundsEstimator(); 138 139 if (!constraintViolationsTable.Rows.Any()) { 140 foreach (var constraint in modelConstraints) { 141 constraintViolationsTable.Rows.Add(new DataRow(constraint.ToString())); 142 averageConstraintViolations.Rows.Add(new DataRow(constraint.ToString())); 143 } 107 144 108 if (!constraintViolationsTable.Rows.Any()) 109 foreach (var constraint in constraints) 110 constraintViolationsTable.Rows.Add(new DataRow(constraint.ToString())); 145 foreach (var extendedConstraint in extendedConstraints.SelectMany(x => x.ShapeConstraints.EnabledConstraints)) { 146 constraintViolationsTable.Rows.Add(new DataRow(extendedConstraint.ToString())); 147 averageConstraintViolations.Rows.Add(new DataRow(extendedConstraint.ToString())); 148 } 149 } 111 150 112 foreach (var constraint in constraints) { 113 var numViolations = trees.Count(tree => IntervalUtil.GetConstraintViolation(constraint, estimator, variableRanges, tree) > 0.0); 114 constraintViolationsTable.Rows[constraint.ToString()].Values.Add(numViolations); 151 var violationsPerTree = new Dictionary<ISymbolicExpressionTree, int>(); 152 var violationsPerConstraint = new Dictionary<string, IList<double>>(); 153 154 foreach(var tree in trees) { 155 var violations = NMSESingleObjectiveConstraintsEvaluator.CalculateShapeConstraintsViolations(problemData, tree, interpreter, estimator, new MersenneTwister()); 156 foreach(var violation in violations) { 157 var constraint = violation.Item1; 158 var error = violation.Item2; 159 if (!violationsPerConstraint.ContainsKey(constraint.ToString())) 160 violationsPerConstraint.Add(constraint.ToString(), new List<double>()); 161 violationsPerConstraint[constraint.ToString()].Add(error); 162 } 163 violationsPerTree.Add(tree, violations.Count(x => x.Item2 > 0)); 164 } 165 166 foreach (var constraint in modelConstraints) { 167 var errors = violationsPerConstraint[constraint.ToString()]; 168 constraintViolationsTable.Rows[constraint.ToString()].Values.Add(errors.Count(x => x > 0)); 169 averageConstraintViolations.Rows[constraint.ToString()].Values.Add(errors.Sum() / errors.Count()); 170 } 171 172 foreach (var extendedConstraint in extendedConstraints.SelectMany(x => x.ShapeConstraints.EnabledConstraints)) { 173 var errors = violationsPerConstraint[extendedConstraint.ToString()]; 174 constraintViolationsTable.Rows[extendedConstraint.ToString()].Values.Add(errors.Count(x => x > 0)); 175 averageConstraintViolations.Rows[extendedConstraint.ToString()].Values.Add(errors.Sum() / errors.Count()); 115 176 } 116 177 … … 121 182 infeasibleSolutionsDataTable.Rows[InfeasibleSolutionsParameterName] 122 183 .Values 123 .Add(trees.Count(t => IntervalUtil.GetConstraintViolations(constraints, estimator, variableRanges, t).Any(x => x > 0.0)));184 .Add(trees.Count(t => violationsPerTree[t] > 0)); 124 185 125 186 return base.Apply(); -
branches/3138_Shape_Constraints_Transformations/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/NMSESingleObjectiveConstraintsEvaluator.cs
r18181 r18213 21 21 22 22 using System; 23 using System.Collections; 23 24 using System.Collections.Generic; 24 25 using System.Linq; … … 29 30 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding; 30 31 using HeuristicLab.Parameters; 32 using HeuristicLab.Random; 31 33 32 34 namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Regression { … … 41 43 private const string BoundsEstimatorParameterName = "BoundsEstimator"; 42 44 private const string PenaltyFactorParameterName = "PenaltyFactor"; 43 private const string ExtendedConstraintsParameterName = "ExtendedConstraints";44 45 45 46 … … 58 59 (IFixedValueParameter<DoubleValue>)Parameters[PenaltyFactorParameterName]; 59 60 60 public IFixedValueParameter<IItemList<ExtendedConstraint>> ExtendedConstraintsParameter =>61 (IFixedValueParameter<IItemList<ExtendedConstraint>>)Parameters[ExtendedConstraintsParameterName];62 61 63 62 … … 86 85 set => PenaltyFactorParameter.Value.Value = value; 87 86 } 88 89 public IEnumerable<ExtendedConstraint> ExtendedConstraints {90 get => ExtendedConstraintsParameter.Value;91 }92 93 94 87 95 88 public override bool Maximization => false; // NMSE is minimized … … 116 109 Parameters.Add(new FixedValueParameter<DoubleValue>(PenaltyFactorParameterName, 117 110 "Punishment factor for constraint violations for soft constraint handling (fitness = NMSE + penaltyFactor * avg(violations)) (default: 1.0)", new DoubleValue(1.0))); 118 Parameters.Add(new FixedValueParameter<ItemList<ExtendedConstraint>>(ExtendedConstraintsParameterName, "", new ItemList<ExtendedConstraint>()));119 111 } 120 112 … … 135 127 var estimationLimits = EstimationLimitsParameter.ActualValue; 136 128 var applyLinearScaling = ApplyLinearScalingParameter.ActualValue.Value; 129 var random = RandomParameter.ActualValue; 137 130 138 131 if (OptimizeParameters) { … … 175 168 176 169 var quality = Calculate(interpreter, tree, estimationLimits.Lower, estimationLimits.Upper, problemData, rows, 177 BoundsEstimator, UseSoftConstraints, PenalityFactor, ExtendedConstraints);170 BoundsEstimator, random, UseSoftConstraints, PenalityFactor); 178 171 QualityParameter.ActualValue = new DoubleValue(quality); 179 172 … … 186 179 double lowerEstimationLimit, double upperEstimationLimit, 187 180 IRegressionProblemData problemData, IEnumerable<int> rows, 188 IBoundsEstimator estimator, 189 bool useSoftConstraints = false, double penaltyFactor = 1.0, 190 IEnumerable<ExtendedConstraint> extendedConstraints = null) { 191 192 var estimatedValues = interpreter.GetSymbolicExpressionTreeValues(tree, problemData.Dataset, rows); 181 IBoundsEstimator estimator, IRandom random, 182 bool useSoftConstraints = false, double penaltyFactor = 1.0) { 183 184 var trainingEstimatedValues = interpreter.GetSymbolicExpressionTreeValues(tree, problemData.Dataset, rows); 193 185 var targetValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows); 194 var constraints = Enumerable.Empty<ShapeConstraint>(); 186 187 var trainingBoundedEstimatedValues = trainingEstimatedValues.LimitToRange(lowerEstimationLimit, upperEstimationLimit); 188 var nmse = OnlineNormalizedMeanSquaredErrorCalculator.Calculate(targetValues, trainingBoundedEstimatedValues, 189 out var errorState); 190 191 if (errorState != OnlineCalculatorError.None) 192 return double.MaxValue; 193 194 var violations = Enumerable.Empty<double>(); 195 195 if (problemData is ShapeConstrainedRegressionProblemData scProbData) { 196 constraints = scProbData.ShapeConstraints.EnabledConstraints; 197 } 198 var intervalCollection = problemData.VariableRanges; 199 200 var boundedEstimatedValues = estimatedValues.LimitToRange(lowerEstimationLimit, upperEstimationLimit); 201 var nmse = OnlineNormalizedMeanSquaredErrorCalculator.Calculate(targetValues, boundedEstimatedValues, 202 out var errorState); 203 204 if (errorState != OnlineCalculatorError.None) { 205 return 1.0; 206 } 207 208 var constraintViolations = IntervalUtil.GetConstraintViolations(constraints, estimator, intervalCollection, tree); 209 210 if (constraintViolations.Any(x => double.IsNaN(x) || double.IsInfinity(x))) { 211 return 1.0; 212 } 196 violations = CalculateShapeConstraintsViolations(scProbData, tree, interpreter, estimator, random).Select(x => x.Item2); 197 } 198 199 if (violations.Any(x => double.IsNaN(x) || double.IsInfinity(x))) 200 return double.MaxValue; 213 201 214 202 if (useSoftConstraints) { … … 216 204 throw new ArgumentException("The parameter has to be >= 0.0.", nameof(penaltyFactor)); 217 205 218 var weightedViolationsAvg = constraints 219 .Zip(constraintViolations, (c, v) => c.Weight * v) 220 .Average(); 221 222 return Math.Min(nmse, 1.0) + penaltyFactor * weightedViolationsAvg; 223 } else if (constraintViolations.Any(x => x > 0.0)) { 224 return 1.0; 225 } 226 227 return nmse; 206 return nmse + penaltyFactor * violations.Average(); 207 } 208 return violations.Any(x => x > 0.0) ? 1.0 : nmse; 209 } 210 211 public static IEnumerable<Tuple<ShapeConstraint, double>> CalculateShapeConstraintsViolations( 212 IShapeConstrainedRegressionProblemData problemData, ISymbolicExpressionTree tree, 213 ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, IBoundsEstimator estimator, 214 IRandom random) { 215 IList<Tuple<ShapeConstraint, double>> violations = new List<Tuple<ShapeConstraint, double>>(); 216 217 var baseConstraints = problemData.ShapeConstraints.EnabledConstraints; 218 var intervalCollection = problemData.VariableRanges; 219 var extendedShapeConstraints = problemData.CheckedExtendedConstraints; 220 var allEstimatedValues = interpreter.GetSymbolicExpressionTreeValues(tree, problemData.Dataset, problemData.AllIndices); 221 222 foreach (var constraint in baseConstraints) 223 violations.Add(Tuple.Create(constraint, IntervalUtil.GetConstraintViolation(constraint, estimator, intervalCollection, tree) * constraint.Weight)); 224 225 IDictionary<string, IList> dict = new Dictionary<string, IList>(); 226 foreach (var varName in problemData.Dataset.VariableNames) { 227 if (varName != problemData.TargetVariable) 228 dict.Add(varName, problemData.Dataset.GetDoubleValues(varName).ToList()); 229 else dict.Add(varName, allEstimatedValues.ToList()); 230 } 231 var tmpDataset = new Dataset(dict.Keys, dict.Values); 232 233 foreach (var extendedConstraint in extendedShapeConstraints) { 234 var enabledConstraints = extendedConstraint.ShapeConstraints.EnabledConstraints; 235 if (enabledConstraints.Any()) { 236 var extendedConstraintExprValues = interpreter.GetSymbolicExpressionTreeValues(extendedConstraint.Tree, tmpDataset, problemData.AllIndices); 237 var extendedConstraintExprInterval = new Interval(extendedConstraintExprValues.Min(), extendedConstraintExprValues.Max()); 238 239 foreach (var constraint in enabledConstraints) { 240 if (constraint.Regions.Count > 0) { 241 // adapt dataset 242 foreach (var kvp in constraint.Regions.GetReadonlyDictionary()) { 243 var lb = double.IsNegativeInfinity(kvp.Value.LowerBound) ? double.MinValue : kvp.Value.LowerBound; 244 var ub = double.IsPositiveInfinity(kvp.Value.UpperBound) ? double.MaxValue : kvp.Value.UpperBound; 245 246 var vals = Enumerable.Range(0, dict[kvp.Key].Count - 2) 247 .Select(x => UniformDistributedRandom.NextDouble(random, lb, ub)) 248 .ToList(); 249 vals.Add(lb); 250 vals.Add(ub); 251 vals.Sort(); 252 dict[kvp.Key] = vals; 253 } 254 // calc again with new regions 255 tmpDataset = new Dataset(dict.Keys, dict.Values); 256 // calc target again 257 allEstimatedValues = interpreter.GetSymbolicExpressionTreeValues(tree, tmpDataset, problemData.AllIndices); 258 dict[problemData.TargetVariable] = allEstimatedValues.ToList(); 259 tmpDataset = new Dataset(dict.Keys, dict.Values); 260 extendedConstraintExprValues = interpreter.GetSymbolicExpressionTreeValues(extendedConstraint.Tree, tmpDataset, problemData.AllIndices); 261 extendedConstraintExprInterval = new Interval(extendedConstraintExprValues.Min(), extendedConstraintExprValues.Max()); 262 } 263 violations.Add(Tuple.Create(constraint, IntervalUtil.GetIntervalError(constraint.Interval, extendedConstraintExprInterval, constraint.Threshold) * constraint.Weight)); 264 } 265 } 266 } 267 return violations; 228 268 } 229 269 … … 234 274 EstimationLimitsParameter.ExecutionContext = context; 235 275 ApplyLinearScalingParameter.ExecutionContext = context; 276 RandomParameter.ExecutionContext = context; 236 277 237 278 var nmse = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree, 238 279 EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, 239 problemData, rows, BoundsEstimator, UseSoftConstraints, PenalityFactor, ExtendedConstraints);280 problemData, rows, BoundsEstimator, RandomParameter.Value, UseSoftConstraints, PenalityFactor); 240 281 241 282 SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = null; 242 283 EstimationLimitsParameter.ExecutionContext = null; 243 284 ApplyLinearScalingParameter.ExecutionContext = null; 285 RandomParameter.ExecutionContext = null; 244 286 245 287 return nmse; -
branches/3138_Shape_Constraints_Transformations/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj
r18180 r18213 160 160 <Compile Include="Creators\SymbolicDataAnalysisExpressionBalancedTreeCreator.cs" /> 161 161 <Compile Include="Crossovers\SymbolicDataAnalysisExpressionDiversityPreservingCrossover.cs" /> 162 <Compile Include="ExtendedConstraint.cs" /> 162 163 <Compile Include="Formatters\InfixExpressionFormatter.cs" /> 163 164 <Compile Include="Formatters\SymbolicDataAnalysisExpressionPythonFormatter.cs" /> -
branches/3138_Shape_Constraints_Transformations/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/IntervalUtil.cs
r17906 r18213 28 28 namespace HeuristicLab.Problems.DataAnalysis.Symbolic { 29 29 public static class IntervalUtil { 30 public static IEnumerable<double> GetConstraintViolations( 31 IEnumerable<ShapeConstraint> constraints, IBoundsEstimator estimator, IntervalCollection intervalCollection, 32 ISymbolicExpressionTree solution) { 33 return constraints.Select(constraint => GetConstraintViolation(constraint, estimator, intervalCollection, solution)).ToList(); 34 } 35 36 public static double GetConstraintViolation( 30 private static void Prepare( 37 31 ShapeConstraint constraint, IBoundsEstimator estimator, IntervalCollection variableRanges, 38 ISymbolicExpressionTree tree ) {32 ISymbolicExpressionTree tree, out ISymbolicExpressionTree preparedTree, out IntervalCollection preparedRanges) { 39 33 var varRanges = variableRanges.GetReadonlyDictionary(); 40 34 … … 55 49 } 56 50 57 if (!constraint.IsDerivative) { 58 return estimator.GetConstraintViolation(tree, regionRanges, constraint); 59 } else { 51 if (constraint.IsDerivative) { 60 52 for (var i = 0; i < constraint.NumberOfDerivations; ++i) { 61 if (!estimator.IsCompatible(tree) || !DerivativeCalculator.IsCompatible(tree)) {53 if (!estimator.IsCompatible(tree) || !DerivativeCalculator.IsCompatible(tree)) 62 54 throw new ArgumentException("The tree contains an unsupported symbol."); 63 }64 55 65 56 tree = DerivativeCalculator.Derive(tree, constraint.Variable); 66 57 } 58 } 67 59 68 return estimator.GetConstraintViolation(tree, regionRanges, constraint); 60 preparedTree = tree; 61 preparedRanges = regionRanges; 62 } 63 64 public static IEnumerable<double> GetConstraintViolations( 65 IEnumerable<ShapeConstraint> constraints, IBoundsEstimator estimator, IntervalCollection intervalCollection, 66 ISymbolicExpressionTree solution) { 67 return constraints.Select(constraint => GetConstraintViolation(constraint, estimator, intervalCollection, solution)).ToList(); 68 } 69 70 public static double GetConstraintViolation( 71 ShapeConstraint constraint, IBoundsEstimator estimator, IntervalCollection variableRanges, 72 ISymbolicExpressionTree tree) { 73 74 Prepare(constraint, estimator, variableRanges, tree, 75 out ISymbolicExpressionTree preparedTree, out IntervalCollection preparedRanges); 76 77 var bounds = estimator.GetModelBound(preparedTree, preparedRanges); 78 79 return GetIntervalError(constraint.Interval, bounds, constraint.Threshold); 80 81 //return estimator.GetConstraintViolation(preparedTree, preparedRanges, constraint); 82 } 83 84 public static double GetIntervalError(Interval target, Interval estimation, Interval? threshold = null) { 85 if(threshold == null) 86 threshold = new Interval(0, 0); 87 88 var error = 0d; 89 if (!target.Contains(estimation.LowerBound)) { 90 var lbError = Math.Abs(estimation.LowerBound - target.LowerBound); 91 error += CalcBoundViolation(lbError, threshold.LowerBound); 69 92 } 93 94 if (!target.Contains(estimation.UpperBound)) { 95 var ubError = Math.Abs(estimation.UpperBound - target.UpperBound); 96 error += CalcBoundViolation(ubError, threshold.UpperBound); 97 } 98 99 return error == 0 ? 0 : error / 2.0; 100 101 } 102 103 private static double CalcBoundViolation(double error, double threshold) { 104 threshold = Math.Abs(threshold); 105 106 if (double.IsNaN(error)) return 1.0; 107 if (double.IsInfinity(error) && !double.IsInfinity(threshold)) return 1.0; 108 if (double.IsInfinity(threshold)) return 0; 109 if (error <= 0) return 0; 110 if (error > threshold) return 1.0; 111 if (threshold > 0) return Math.Min(1.0, error / threshold); 112 return 1.0; 70 113 } 71 114 } -
branches/3138_Shape_Constraints_Transformations/HeuristicLab.Problems.DataAnalysis/3.4/HeuristicLab.Problems.DataAnalysis-3.4.csproj
r17960 r18213 188 188 <Compile Include="Interfaces\Regression\IConfidenceRegressionModel.cs" /> 189 189 <Compile Include="Interfaces\Regression\IConfidenceRegressionSolution.cs" /> 190 <Compile Include="Interfaces\Regression\IExtendedConstraint.cs" /> 190 191 <Compile Include="Interfaces\Regression\IRegressionEnsembleModel.cs"> 191 192 <SubType>Code</SubType> … … 308 309 <Private>False</Private> 309 310 </ProjectReference> 311 <ProjectReference Include="..\..\HeuristicLab.Encodings.SymbolicExpressionTreeEncoding\3.4\HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4.csproj"> 312 <Project>{06D4A186-9319-48A0-BADE-A2058D462EEA}</Project> 313 <Name>HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4</Name> 314 </ProjectReference> 310 315 <ProjectReference Include="..\..\HeuristicLab.Optimization\3.3\HeuristicLab.Optimization-3.3.csproj"> 311 316 <Project>{14AB8D24-25BC-400C-A846-4627AA945192}</Project> -
branches/3138_Shape_Constraints_Transformations/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/ShapeConstrainedRegressionProblemData.cs
r18180 r18213 34 34 public class ShapeConstrainedRegressionProblemData : RegressionProblemData, IShapeConstrainedRegressionProblemData { 35 35 protected const string ShapeConstraintsParameterName = "ShapeConstraints"; 36 protected const string ExtendedConstraintsParameterName = "ExtendedConstraints"; 36 37 37 38 #region default data … … 97 98 defaultTargetVariable = "y_noise"; 98 99 defaultShapeConstraints = new ShapeConstraints { 99 new ShapeConstraint(new Interval(0, 2), 1.0 ),100 new ShapeConstraint("x", 1, new Interval(0, double.PositiveInfinity), 1.0 )100 new ShapeConstraint(new Interval(0, 2), 1.0, new Interval(0,0)), 101 new ShapeConstraint("x", 1, new Interval(0, double.PositiveInfinity), 1.0, new Interval(0,0)) 101 102 }; 102 103 defaultVariableRanges = defaultDataset.GetVariableRanges(); … … 116 117 problemData.Parameters.Add(new FixedValueParameter<IntervalCollection>(VariableRangesParameterName, "", new IntervalCollection())); 117 118 problemData.Parameters.Add(new FixedValueParameter<ShapeConstraints>(ShapeConstraintsParameterName, "", new ShapeConstraints())); 119 problemData.Parameters.Add(new FixedValueParameter<CheckedItemList<IExtendedConstraint>>(ExtendedConstraintsParameterName, "", new CheckedItemList<IExtendedConstraint>())); 118 120 emptyProblemData = problemData; 119 121 } … … 122 124 public IFixedValueParameter<ShapeConstraints> ShapeConstraintParameter => (IFixedValueParameter<ShapeConstraints>)Parameters[ShapeConstraintsParameterName]; 123 125 public ShapeConstraints ShapeConstraints => ShapeConstraintParameter.Value; 126 127 public IFixedValueParameter<CheckedItemList<IExtendedConstraint>> ExtendedConstraintsParameter => 128 (IFixedValueParameter<CheckedItemList<IExtendedConstraint>>)Parameters[ExtendedConstraintsParameterName]; 129 public CheckedItemList<IExtendedConstraint> ExtendedConstraints => ExtendedConstraintsParameter.Value; 130 public IEnumerable<IExtendedConstraint> CheckedExtendedConstraints => ExtendedConstraints.CheckedItems.Select(x => x.Value); 124 131 125 132 [StorableConstructor] … … 132 139 [StorableHook(HookType.AfterDeserialization)] 133 140 private void AfterDeserialization() { 141 if (!Parameters.ContainsKey(ExtendedConstraintsParameterName)) 142 Parameters.Add(new FixedValueParameter<CheckedItemList<IExtendedConstraint>>(ExtendedConstraintsParameterName, "", new CheckedItemList<IExtendedConstraint>())); 143 134 144 RegisterEventHandlers(); 135 145 } … … 158 168 if (sc == null) sc = new ShapeConstraints(); 159 169 Parameters.Add(new FixedValueParameter<ShapeConstraints>(ShapeConstraintsParameterName, "Specifies the shape constraints for the regression problem.", (ShapeConstraints)sc.Clone())); 170 Parameters.Add(new FixedValueParameter<CheckedItemList<IExtendedConstraint>>(ExtendedConstraintsParameterName, "", new CheckedItemList<IExtendedConstraint>())); 160 171 RegisterEventHandlers(); 161 172 } … … 169 180 ShapeConstraints.ItemsMoved += ShapeConstraints_Changed; 170 181 ShapeConstraints.ItemsReplaced += ShapeConstraints_Changed; 182 183 ExtendedConstraints.CheckedItemsChanged += ShapeConstraints_Changed; 184 ExtendedConstraints.CollectionReset += ShapeConstraints_Changed; 185 ExtendedConstraints.ItemsAdded += ShapeConstraints_Changed; 186 ExtendedConstraints.ItemsRemoved += ShapeConstraints_Changed; 187 ExtendedConstraints.ItemsMoved += ShapeConstraints_Changed; 188 ExtendedConstraints.ItemsReplaced += ShapeConstraints_Changed; 171 189 } 172 190 -
branches/3138_Shape_Constraints_Transformations/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/ShapeConstraint.cs
r17960 r18213 106 106 } 107 107 108 [Storable] 109 private Interval threshold = new Interval(0, 0); 110 public Interval Threshold { 111 get => threshold; 112 set { 113 if (threshold == value) 114 return; 115 threshold = value; 116 OnToStringChanged(); 117 OnChanged(); 118 } 119 } 120 108 121 [StorableConstructor] 109 122 private ShapeConstraint(StorableConstructorFlag _) : base(_) { } … … 115 128 116 129 // without derivation 117 public ShapeConstraint(Interval interval, double weight )130 public ShapeConstraint(Interval interval, double weight, Interval threshold) 118 131 : this(string.Empty, 0, 119 interval, new IntervalCollection(), weight ) { }120 121 public ShapeConstraint(Interval interval, IntervalCollection regions, double weight )132 interval, new IntervalCollection(), weight, threshold) { } 133 134 public ShapeConstraint(Interval interval, IntervalCollection regions, double weight, Interval threshold) 122 135 : this(string.Empty, 0, 123 interval, regions, weight ) { }136 interval, regions, weight, threshold) { } 124 137 125 138 public ShapeConstraint(string variable, int numberOfDerivations, 126 Interval interval, double weight )139 Interval interval, double weight, Interval threshold) 127 140 : this(variable, numberOfDerivations, 128 interval, new IntervalCollection(), weight ) { }141 interval, new IntervalCollection(), weight, threshold) { } 129 142 130 143 public ShapeConstraint(string variable, int numberOfDerivations, 131 Interval interval, IntervalCollection regions, double weight ) {144 Interval interval, IntervalCollection regions, double weight, Interval threshold) { 132 145 Variable = variable; 133 146 NumberOfDerivations = numberOfDerivations; … … 135 148 Regions = regions; 136 149 Weight = weight; 150 Threshold = threshold; 137 151 } 138 152 … … 148 162 Regions = cloner.Clone(original.Regions); 149 163 Weight = original.weight; 164 Threshold = original.threshold; 150 165 } 151 166 … … 175 190 if (!IsDerivative) { 176 191 expression = string.Format($"f in [{write(Interval.LowerBound)} .. {write(Interval.UpperBound)}]"); 177 if (Regions != null) { 178 foreach (var region in Regions.GetReadonlyDictionary()) 179 expression += $", {region.Key} in [{write(region.Value.LowerBound)} .. {write(region.Value.UpperBound)}]"; 192 } else { 193 var derivationString = string.Empty; 194 switch (numberOfDerivations) { 195 case 1: 196 derivationString = ""; break; 197 case 2: 198 derivationString = "²"; break; 199 case 3: 200 derivationString = "³"; break; 180 201 } 181 if (Weight != 1.0) { 182 expression += $" weight: {weight}"; 183 } 184 185 return expression; 186 } 187 188 var derivationString = string.Empty; 189 switch (numberOfDerivations) { 190 case 1: 191 derivationString = ""; break; 192 case 2: 193 derivationString = "²"; break; 194 case 3: 195 derivationString = "³"; break; 196 } 197 expression = string.Format($"∂{derivationString}f/∂{Variable}{derivationString} in [{write(Interval.LowerBound)} .. {write(Interval.UpperBound)}]"); 198 if (Regions != null) { 202 expression = string.Format($"∂{derivationString}f/∂{Variable}{derivationString} in [{write(Interval.LowerBound)} .. {write(Interval.UpperBound)}]"); 203 } 204 205 if (Regions != null) 199 206 foreach (var region in Regions.GetReadonlyDictionary()) 200 207 expression += $", {region.Key} in [{write(region.Value.LowerBound)} .. {write(region.Value.UpperBound)}]"; 201 } 202 if (Weight != 1.0) {208 209 if (Weight != 1.0) 203 210 expression += $" weight: {weight}"; 204 } 211 212 if (Threshold.LowerBound != 0 || Threshold.UpperBound != 0) 213 expression += $" threshold in [{write(Threshold.LowerBound)} .. {write(Threshold.UpperBound)}]"; 214 205 215 return expression; 206 216 } -
branches/3138_Shape_Constraints_Transformations/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/ShapeConstraintsParser.cs
r17960 r18213 75 75 private const string variableRegex = @"(['](?<varName>.*)[']|(?<varName>[^\s²³]+))\s*"; 76 76 private const string weightRegex = @"\s*(weight:\s*(?<weight>\S*))?"; 77 private const string thresholdRegex = @"\s*(threshold\s*in\s*(?<threshold> " + intervalRegex + @"))?"; 77 78 public static ShapeConstraint ParseFunctionRangeConstraint(string expr) { 78 79 if (!expr.StartsWith("f")) throw new ArgumentException($"Invalid function range constraint {expr} (e.g. f in [1..2])"); … … 89 90 // df/d'x' in [0 .. 10] weight: 2.0 90 91 // df / d'x' in [0..10], 'x' in [1 .. 3] 91 // df / d'x' in [0..10], 'x' in [1 .. 3], y in [10..30] weight: 1.2 92 // df / d'x' in [0..10], 'x' in [1 .. 3], y in [10..30] weight: 1.2 threshold in [-10 .. 10] 92 93 93 94 var match = Regex.Match(targetConstraint, … … 99 100 intervalRegex + 100 101 @")*" + 101 weightRegex 102 weightRegex + 103 thresholdRegex 102 104 ); 103 105 … … 110 112 var interval = new Interval(lowerBound, upperBound); 111 113 var weight = 1.0; 114 var threshold = new Interval(0, 0); 115 int intervalIdx = 1; 116 var lowerboundCount = match.Groups["lowerBound"].Captures.Count; 117 var upperboundCount = match.Groups["upperBound"].Captures.Count; 112 118 113 119 if (match.Groups["weight"].Success && !string.IsNullOrWhiteSpace(match.Groups["weight"].Value)) 114 120 weight = ParseAndValidateDouble(match.Groups["weight"].Value); 121 122 if (match.Groups["threshold"].Success) { 123 var thresholdLb = ParseIntervalBounds(match.Groups["lowerBound"].Captures[lowerboundCount - intervalIdx].Value); 124 var thresholdUb = ParseIntervalBounds(match.Groups["upperBound"].Captures[lowerboundCount - intervalIdx].Value); 125 intervalIdx++; 126 threshold = new Interval(thresholdLb, thresholdUb); 127 } 115 128 116 129 if (match.Groups["varName"].Success) { … … 127 140 throw new ArgumentException($"The constraint {expr} has multiple regions of the same variable."); 128 141 } 129 return new ShapeConstraint(interval, regions, weight );142 return new ShapeConstraint(interval, regions, weight, threshold); 130 143 } else 131 return new ShapeConstraint(interval, weight );144 return new ShapeConstraint(interval, weight, threshold); 132 145 } else 133 146 throw new ArgumentException($"The target constraint {expr} is not valid."); … … 148 161 intervalRegex + 149 162 @")*" + 150 weightRegex 163 weightRegex + 164 thresholdRegex 151 165 ); 152 166 … … 172 186 var interval = new Interval(lowerBound, upperBound); 173 187 var weight = 1.0; 188 var threshold = new Interval(0, 0); 189 int intervalIdx = 1; 190 var lowerboundCount = match.Groups["lowerBound"].Captures.Count; 191 var upperboundCount = match.Groups["upperBound"].Captures.Count; 174 192 175 193 if (match.Groups["weight"].Success && !string.IsNullOrWhiteSpace(match.Groups["weight"].Value)) 176 194 weight = ParseAndValidateDouble(match.Groups["weight"].Value); 195 196 if (match.Groups["threshold"].Success) { 197 var thresholdLb = ParseIntervalBounds(match.Groups["lowerBound"].Captures[lowerboundCount - intervalIdx].Value); 198 var thresholdUb = ParseIntervalBounds(match.Groups["upperBound"].Captures[lowerboundCount - intervalIdx].Value); 199 intervalIdx++; 200 threshold = new Interval(thresholdLb, thresholdUb); 201 } 177 202 178 203 if (match.Groups["varName"].Captures.Count > 1) { … … 189 214 throw new ArgumentException($"The constraint {expr} has multiple regions of the same variable."); 190 215 } 191 return new ShapeConstraint(variable, numberOfDerivation, interval, regions, weight );216 return new ShapeConstraint(variable, numberOfDerivation, interval, regions, weight, threshold); 192 217 } else 193 return new ShapeConstraint(variable, numberOfDerivation, interval, weight );218 return new ShapeConstraint(variable, numberOfDerivation, interval, weight, threshold); 194 219 } else 195 220 throw new ArgumentException($"The derivation constraint {expr} is not valid."); -
branches/3138_Shape_Constraints_Transformations/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Regression/IShapeConstrainedRegressionProblemData.cs
r17960 r18213 20 20 #endregion 21 21 22 using System.Collections.Generic; 22 23 using HEAL.Attic; 23 24 … … 26 27 public interface IShapeConstrainedRegressionProblemData : IRegressionProblemData { 27 28 ShapeConstraints ShapeConstraints { get; } 29 IEnumerable<IExtendedConstraint> CheckedExtendedConstraints { get; } 28 30 } 29 31 }
Note: See TracChangeset
for help on using the changeset viewer.