Changeset 15064 for branches/EfficientGlobalOptimization/HeuristicLab.Algorithms.EGO/InfillCriteria/ExpectedImprovement.cs
- Timestamp:
- 06/26/17 09:10:56 (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/EfficientGlobalOptimization/HeuristicLab.Algorithms.EGO/InfillCriteria/ExpectedImprovement.cs
r14818 r15064 24 24 using HeuristicLab.Common; 25 25 using HeuristicLab.Core; 26 using HeuristicLab.Data;27 26 using HeuristicLab.Encodings.RealVectorEncoding; 28 using HeuristicLab.Parameters;29 27 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; 30 28 using HeuristicLab.Problems.DataAnalysis; … … 35 33 [StorableClass] 36 34 [Item("ExpectedImprovementMeassure", "Extension of the Expected Improvement to a weighted version by ANDRAS SÓBESTER , STEPHEN J. LEARY and ANDY J. KEANE in \n On the Design of Optimization Strategies Based on Global Response Surface Approximation Models")] 37 public class ExpectedImprovement : InfillCriterionBase { 38 39 #region ParameterNames 40 private const string ExploitationWeightParameterName = "ExploitationWeight"; 41 #endregion 42 43 #region ParameterProperties 44 public IFixedValueParameter<DoubleValue> ExploitationWeightParameter => Parameters[ExploitationWeightParameterName] as IFixedValueParameter<DoubleValue>; 45 46 #endregion 47 48 #region Properties 49 protected double ExploitationWeight => ExploitationWeightParameter.Value.Value; 50 51 [Storable] 52 protected double YMin; 53 #endregion 54 55 #region HL-Constructors, Serialization and Cloning 35 public sealed class ExpectedImprovement : ExpectedImprovementBase { 36 #region Constructors, Serialization and Cloning 56 37 [StorableConstructor] 57 protected ExpectedImprovement(bool deserializing) : base(deserializing) { } 58 [StorableHook(HookType.AfterDeserialization)] 59 private void AfterDeserialization() { 60 RegisterEventhandlers(); 61 } 62 protected ExpectedImprovement(ExpectedImprovement original, Cloner cloner) : base(original, cloner) { 63 RegisterEventhandlers(); 64 } 65 public ExpectedImprovement() { 66 Parameters.Add(new FixedValueParameter<DoubleValue>(ExploitationWeightParameterName, "A value between 0 and 1 indicating the focus on exploration (0) or exploitation (1)", new DoubleValue(0.5))); 67 RegisterEventhandlers(); 68 } 38 private ExpectedImprovement(bool deserializing) : base(deserializing) { } 39 private ExpectedImprovement(ExpectedImprovement original, Cloner cloner) : base(original, cloner) { } 40 public ExpectedImprovement() { } 69 41 public override IDeepCloneable Clone(Cloner cloner) { 70 42 return new ExpectedImprovement(this, cloner); … … 76 48 var yhat = model.GetEstimation(vector); 77 49 var s = Math.Sqrt(model.GetVariance(vector)); 78 return GetEstimatedImprovement( YMin, yhat, s, ExploitationWeight);50 return GetEstimatedImprovement(BestFitness, yhat, s, ExploitationWeight, ExpensiveMaximization); 79 51 } 80 52 81 p ublic override bool Maximization() {82 return true;53 protected override double Evaluate(RealVector vector, double estimatedFitness, double estimatedStandardDeviation) { 54 return GetEstimatedImprovement(BestFitness, estimatedFitness, estimatedStandardDeviation, ExploitationWeight, ExpensiveMaximization); 83 55 } 84 56 85 protected override void Initialize() { 86 if (ExpensiveMaximization) throw new NotImplementedException("Expected Improvement for maximization not yet implemented"); 87 var model = RegressionSolution.Model as IConfidenceRegressionModel; 88 if (model == null) throw new ArgumentException("can not calculate EI without confidence measure"); 89 YMin = RegressionSolution.ProblemData.TargetVariableTrainingValues.Min(); 57 protected override double FindBestFitness(IConfidenceRegressionSolution solution) { 58 return ExpensiveMaximization ? solution.ProblemData.TargetVariableTrainingValues.Max() : solution.ProblemData.TargetVariableTrainingValues.Min(); 90 59 } 91 92 #region Eventhandling93 private void RegisterEventhandlers() {94 DeregisterEventhandlers();95 ExploitationWeightParameter.Value.ValueChanged += OnExploitationWeightChanged;96 }97 private void DeregisterEventhandlers() {98 ExploitationWeightParameter.Value.ValueChanged -= OnExploitationWeightChanged;99 }100 private void OnExploitationWeightChanged(object sender, EventArgs e) {101 ExploitationWeightParameter.Value.ValueChanged -= OnExploitationWeightChanged;102 ExploitationWeightParameter.Value.Value = Math.Max(0, Math.Min(ExploitationWeight, 1));103 ExploitationWeightParameter.Value.ValueChanged += OnExploitationWeightChanged;104 }105 #endregion106 107 #region Helpers108 protected static double GetEstimatedImprovement(double ymin, double yhat, double s, double w) {109 if (Math.Abs(s) < double.Epsilon) return 0;110 var val = (ymin - yhat) / s;111 var res = w * (ymin - yhat) * StandardNormalDistribution(val) + (1 - w) * s * StandardNormalDensity(val);112 return double.IsInfinity(res) || double.IsNaN(res) ? 0 : res;113 }114 115 private static double StandardNormalDensity(double x) {116 if (Math.Abs(x) > 10) return 0;117 return Math.Exp(-0.5 * x * x) / Math.Sqrt(2 * Math.PI);118 }119 120 //taken from https://www.johndcook.com/blog/2009/01/19/stand-alone-error-function-erf/121 private static double StandardNormalDistribution(double x) {122 if (x > 10) return 1;123 if (x < -10) return 0;124 const double a1 = 0.254829592;125 const double a2 = -0.284496736;126 const double a3 = 1.421413741;127 const double a4 = -1.453152027;128 const double a5 = 1.061405429;129 const double p = 0.3275911;130 var sign = x < 0 ? -1 : 1;131 x = Math.Abs(x) / Math.Sqrt(2.0);132 var t = 1.0 / (1.0 + p * x);133 var y = 1.0 - ((((a5 * t + a4) * t + a3) * t + a2) * t + a1) * t * Math.Exp(-x * x);134 return 0.5 * (1.0 + sign * y);135 }136 #endregion137 60 } 138 61 }
Note: See TracChangeset
for help on using the changeset viewer.