source: branches/EfficientGlobalOptimization/HeuristicLab.Algorithms.EGO/EfficientGlobalOptimizationAlgorithm.cs @ 15338

Last change on this file since 15338 was 15338, checked in by bwerth, 5 years ago

#2745 fixed bug concerning new Start and StartAsync methods; passed CancellationToken to sub algorithms

File size: 29.1 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections.Generic;
24using System.Linq;
25using System.Threading;
26using HeuristicLab.Algorithms.DataAnalysis;
27using HeuristicLab.Analysis;
28using HeuristicLab.Common;
29using HeuristicLab.Core;
30using HeuristicLab.Data;
31using HeuristicLab.Encodings.RealVectorEncoding;
32using HeuristicLab.Optimization;
33using HeuristicLab.Parameters;
34using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
35using HeuristicLab.Problems.DataAnalysis;
36using HeuristicLab.Problems.Instances;
37using HeuristicLab.Random;
38
39namespace HeuristicLab.Algorithms.EGO {
40  [StorableClass]
41  [Creatable(CreatableAttribute.Categories.Algorithms, Priority = 95)]
42  [Item("EfficientGlobalOptimizationAlgorithm", "Solves a problem by sequentially learning a model, solving a subproblem on the model and evaluating the best found solution for this subproblem.")]
43  public class EfficientGlobalOptimizationAlgorithm : BasicAlgorithm, ISurrogateAlgorithm<RealVector> {
44    #region Basic-Alg-Essentials
45    public override bool SupportsPause => true;
46    public override Type ProblemType => typeof(SingleObjectiveBasicProblem<IEncoding>);
47    public new SingleObjectiveBasicProblem<IEncoding> Problem {
48      get { return (SingleObjectiveBasicProblem<IEncoding>)base.Problem; }
49      set { base.Problem = value; }
50    }
51    #endregion
52
53    #region ParameterNames
54    private const string GenerationSizeParameterName = "GenerationSize";
55    private const string InfillCriterionParameterName = "InfillCriterion";
56    private const string InfillOptimizationAlgorithmParameterName = "InfillOptimizationAlgorithm";
57    private const string InfillOptimizationRestartsParameterName = "InfillOptimizationRestarts";
58    private const string InitialEvaluationsParameterName = "Initial Evaluations";
59    private const string MaximumEvaluationsParameterName = "Maximum Evaluations";
60    private const string MaximumRuntimeParameterName = "Maximum Runtime";
61    private const string RegressionAlgorithmParameterName = "RegressionAlgorithm";
62    private const string SeedParameterName = "Seed";
63    private const string SetSeedRandomlyParameterName = "SetSeedRandomly";
64    private const string MaximalDataSetSizeParameterName = "MaximalDataSetSize";
65    private const string RemoveDuplicatesParamterName = "RemoveDuplicates";
66    private const string InitialSamplesParameterName = "InitialSamplesFile";
67    private const string BaselineVectorParameterName = "BaselineVector";
68    private const string InitialSamplingPlanParamterName = "InitialSamplingPlan";
69    #endregion
70
71    #region ResultNames
72    private const string BestQualityResultName = "Best Quality";
73    private const string BestSolutionResultName = "Best Solution";
74    private const string EvaluatedSoultionsResultName = "EvaluatedSolutions";
75    private const string IterationsResultName = "Iterations";
76    private const string RegressionSolutionResultName = "Model";
77    private const string QualitiesChartResultName = "Qualities";
78    private const string BestQualitiesRowResultName = "Best Quality";
79    private const string CurrentQualitiesRowResultName = "Current Quality";
80    private const string WorstQualitiesRowResultName = "Worst Quality";
81    #endregion
82
83    #region ParameterProperties
84    public IFixedValueParameter<IntValue> GenerationSizeParemeter => Parameters[GenerationSizeParameterName] as IFixedValueParameter<IntValue>;
85    public IConstrainedValueParameter<IInfillCriterion> InfillCriterionParameter => Parameters[InfillCriterionParameterName] as IConstrainedValueParameter<IInfillCriterion>;
86    public IValueParameter<Algorithm> InfillOptimizationAlgorithmParameter => Parameters[InfillOptimizationAlgorithmParameterName] as IValueParameter<Algorithm>;
87    public IFixedValueParameter<IntValue> InfillOptimizationRestartsParemeter => Parameters[InfillOptimizationRestartsParameterName] as IFixedValueParameter<IntValue>;
88    public IFixedValueParameter<IntValue> InitialEvaluationsParameter => Parameters[InitialEvaluationsParameterName] as IFixedValueParameter<IntValue>;
89    public IFixedValueParameter<IntValue> MaximumEvaluationsParameter => Parameters[MaximumEvaluationsParameterName] as IFixedValueParameter<IntValue>;
90    public IFixedValueParameter<IntValue> MaximumRuntimeParameter => Parameters[MaximumRuntimeParameterName] as IFixedValueParameter<IntValue>;
91    public IValueParameter<IDataAnalysisAlgorithm<IRegressionProblem>> RegressionAlgorithmParameter => Parameters[RegressionAlgorithmParameterName] as IValueParameter<IDataAnalysisAlgorithm<IRegressionProblem>>;
92    public IFixedValueParameter<IntValue> SeedParameter => Parameters[SeedParameterName] as IFixedValueParameter<IntValue>;
93    public IFixedValueParameter<BoolValue> SetSeedRandomlyParameter => Parameters[SetSeedRandomlyParameterName] as IFixedValueParameter<BoolValue>;
94    public IFixedValueParameter<IntValue> MaximalDataSetSizeParameter => Parameters[MaximalDataSetSizeParameterName] as IFixedValueParameter<IntValue>;
95    public IFixedValueParameter<BoolValue> RemoveDuplicatesParameter => Parameters[RemoveDuplicatesParamterName] as IFixedValueParameter<BoolValue>;
96    public IFixedValueParameter<FileValue> InitialSamplesParameter => Parameters[InitialSamplesParameterName] as IFixedValueParameter<FileValue>;
97    public IValueParameter<RealVector> BaselineVectorParameter => Parameters[BaselineVectorParameterName] as IValueParameter<RealVector>;
98    public IConstrainedValueParameter<IInitialSampling> InitialSamplingPlanParameter => Parameters[InitialSamplingPlanParamterName] as IConstrainedValueParameter<IInitialSampling>;
99    #endregion
100
101    #region Properties
102    public int GenerationSize => GenerationSizeParemeter.Value.Value;
103    public IInfillCriterion InfillCriterion => InfillCriterionParameter.Value;
104    public Algorithm InfillOptimizationAlgorithm => InfillOptimizationAlgorithmParameter.Value;
105    public int InfillOptimizationRestarts => InfillOptimizationRestartsParemeter.Value.Value;
106    public int InitialEvaluations => InitialEvaluationsParameter.Value.Value;
107    public int MaximumEvaluations => MaximumEvaluationsParameter.Value.Value;
108    public int MaximumRuntime => MaximumRuntimeParameter.Value.Value;
109    public IDataAnalysisAlgorithm<IRegressionProblem> RegressionAlgorithm => RegressionAlgorithmParameter.Value;
110    public int Seed => SeedParameter.Value.Value;
111    public bool SetSeedRandomly => SetSeedRandomlyParameter.Value.Value;
112    public int MaximalDatasetSize => MaximalDataSetSizeParameter.Value.Value;
113    private IEnumerable<Tuple<RealVector, double>> DataSamples => Samples.Count > MaximalDatasetSize && MaximalDatasetSize > 0
114      ? Samples.Skip(Samples.Count - MaximalDatasetSize)
115      : Samples;
116    private bool RemoveDuplicates => RemoveDuplicatesParameter.Value.Value;
117    private RealVector BaselineVector => BaselineVectorParameter.Value;
118    private IInitialSampling InitialSamplingPlan => InitialSamplingPlanParameter.Value;
119    #endregion
120
121    #region StorableProperties
122    [Storable]
123    private IRandom Random = new MersenneTwister();
124    [Storable]
125    private List<Tuple<RealVector, double>> Samples;
126    [Storable]
127    private List<Tuple<RealVector, double>> InitialSamples;
128    #endregion
129
130    #region ResultsProperties
131    private double ResultsBestQuality {
132      get { return ((DoubleValue)Results[BestQualityResultName].Value).Value; }
133      set { ((DoubleValue)Results[BestQualityResultName].Value).Value = value; }
134    }
135    private RealVector ResultsBestSolution {
136      get { return (RealVector)Results[BestSolutionResultName].Value; }
137      set { Results[BestSolutionResultName].Value = value; }
138    }
139    private int ResultsEvaluations {
140      get { return ((IntValue)Results[EvaluatedSoultionsResultName].Value).Value; }
141      set { ((IntValue)Results[EvaluatedSoultionsResultName].Value).Value = value; }
142    }
143    private int ResultsIterations {
144      get { return ((IntValue)Results[IterationsResultName].Value).Value; }
145      set { ((IntValue)Results[IterationsResultName].Value).Value = value; }
146    }
147    private DataTable ResultsQualities => (DataTable)Results[QualitiesChartResultName].Value;
148    private DataRow ResultsQualitiesBest => ResultsQualities.Rows[BestQualitiesRowResultName];
149    private DataRow ResultsQualitiesWorst => ResultsQualities.Rows[WorstQualitiesRowResultName];
150    private DataRow ResultsQualitiesIteration => ResultsQualities.Rows[CurrentQualitiesRowResultName];
151    private IRegressionSolution ResultsModel {
152      get { return (IRegressionSolution)Results[RegressionSolutionResultName].Value; }
153      set { Results[RegressionSolutionResultName].Value = value; }
154    }
155    #endregion
156
157    #region HLConstructors
158    [StorableConstructor]
159    protected EfficientGlobalOptimizationAlgorithm(bool deserializing) : base(deserializing) { }
160    [StorableHook(HookType.AfterDeserialization)]
161    protected void AfterDeseialization() {
162      RegisterEventhandlers();
163    }
164    protected EfficientGlobalOptimizationAlgorithm(EfficientGlobalOptimizationAlgorithm original, Cloner cloner) : base(original, cloner) {
165      Random = cloner.Clone(Random);
166      if (original.Samples != null) Samples = original.Samples.Select(x => new Tuple<RealVector, double>(cloner.Clone(x.Item1), x.Item2)).ToList();
167      if (original.InitialSamples != null) InitialSamples = original.InitialSamples.Select(x => new Tuple<RealVector, double>(cloner.Clone(x.Item1), x.Item2)).ToList();
168      RegisterEventhandlers();
169    }
170    public override IDeepCloneable Clone(Cloner cloner) { return new EfficientGlobalOptimizationAlgorithm(this, cloner); }
171    public EfficientGlobalOptimizationAlgorithm() {
172      IProblemInstanceExporter dummy = new RegressionProblem(); //this variable is irrelevant
173      //the dummy variable enforces a using-Statement for HeuristicLab.Problems.Instances
174      //"new ValueParameter<IDataAnalysisAlgorithm<IRegressionProblem>>" requires no using using-Statement, but nontheless it requires HeuristicLab.Problems.Instances to be referenced 
175      //Having HeuristicLab.Problems.Instances referenced but not used, causes the Essential-Unit-tests to fail.
176
177      var cmaes = new CMAEvolutionStrategy.CMAEvolutionStrategy {
178        MaximumGenerations = 300,
179        PopulationSize = 50
180      };
181      var model = new GaussianProcessRegression {
182        Problem = new RegressionProblem()
183      };
184      model.CovarianceFunctionParameter.Value = new CovarianceRationalQuadraticIso();
185      Parameters.Add(new FixedValueParameter<IntValue>(MaximumEvaluationsParameterName, "", new IntValue(int.MaxValue)));
186      Parameters.Add(new FixedValueParameter<IntValue>(InitialEvaluationsParameterName, "", new IntValue(10)));
187      Parameters.Add(new FixedValueParameter<IntValue>(MaximumRuntimeParameterName, "The maximum runtime in seconds after which the algorithm stops. Use -1 to specify no limit for the runtime", new IntValue(-1)));
188      Parameters.Add(new FixedValueParameter<IntValue>(SeedParameterName, "The random seed used to initialize the new pseudo random number generator.", new IntValue(0)));
189      Parameters.Add(new FixedValueParameter<BoolValue>(SetSeedRandomlyParameterName, "True if the random seed should be set to a random value, otherwise false.", new BoolValue(true)));
190      Parameters.Add(new ValueParameter<IDataAnalysisAlgorithm<IRegressionProblem>>(RegressionAlgorithmParameterName, "The model used to approximate the problem", model));
191      Parameters.Add(new ValueParameter<Algorithm>(InfillOptimizationAlgorithmParameterName, "The algorithm used to solve the expected improvement subproblem", cmaes));
192      Parameters.Add(new FixedValueParameter<IntValue>(InfillOptimizationRestartsParameterName, "Number of restarts of the SubAlgortihm to avoid local optima", new IntValue(1)));
193      Parameters.Add(new FixedValueParameter<IntValue>(GenerationSizeParameterName, "Number points that are sampled every iteration (stadard EGO: 1)", new IntValue(1)));
194      Parameters.Add(new FixedValueParameter<IntValue>(MaximalDataSetSizeParameterName, "The maximum number of sample points used to generate the model. Set 0 or less to use always all samples ", new IntValue(-1)));
195      Parameters.Add(new FixedValueParameter<BoolValue>(RemoveDuplicatesParamterName, "Wether duplicate samples should be replaced by a single sample with an averaged quality. This GREATLY decreases the chance of ill conditioned models (unbuildable models) but is not theoretically sound as the model ignores the increasing certainty in this region"));
196      Parameters.Add(new FixedValueParameter<FileValue>(InitialSamplesParameterName, "The file specifying some initial samples used to jump start the algorithm. These samples are not counted as evaluations. If InitialEvaluations is more than the samples specified in the file, the rest is uniformly random generated and evaluated.", new FileValue()));
197      Parameters.Add(new ValueParameter<RealVector>(BaselineVectorParameterName, "A vector used to create a baseline, this vector is evaluated once and is not part of the modeling process (has no influence on algorithm performance)"));
198      var eqi = new ExpectedQuantileImprovement();
199      eqi.MaxEvaluationsParameter.Value = MaximumEvaluationsParameter.Value;
200      var criteria = new ItemSet<IInfillCriterion> { new ExpectedImprovement(), new AugmentedExpectedImprovement(), new ExpectedQuality(), eqi, new MinimalQuantileCriterium(), new PluginExpectedImprovement() };
201      Parameters.Add(new ConstrainedValueParameter<IInfillCriterion>(InfillCriterionParameterName, "Decision what value should decide the next sample", criteria, criteria.First()));
202      var intialSamplingPlans = new ItemSet<IInitialSampling> { new UniformRandomSampling(), new LatinHyperCubeDesignCreator() };
203      Parameters.Add(new ConstrainedValueParameter<IInitialSampling>(InitialSamplingPlanParamterName, "Determies the initial samples from which the first model can be built.", intialSamplingPlans, intialSamplingPlans.First()));
204      SetInfillProblem();
205      RegisterEventhandlers();
206    }
207    #endregion
208    public void SetInitialSamples(RealVector[] individuals, double[] qualities) {
209      InitialSamples = individuals.Zip(qualities, (individual, d) => new Tuple<RealVector, double>(individual, d)).ToList();
210    }
211    protected override void Initialize(CancellationToken cancellationToken) {
212      base.Initialize(cancellationToken);
213      //encoding
214      var enc = Problem.Encoding as RealVectorEncoding;
215      if (enc == null) throw new ArgumentException("The EGO algorithm can only be applied to RealVectorEncodings");
216      var infillProblem = InfillOptimizationAlgorithm.Problem as InfillProblem;
217      if (infillProblem == null) throw new ArgumentException("InfillOptimizationAlgorithm has no InfillProblem. Troubles with Eventhandling?");
218
219      //random
220      if (SetSeedRandomly) SeedParameter.Value.Value = new System.Random().Next();
221      Random.Reset(Seed);
222      Samples = InitialSamples?.ToList() ?? new List<Tuple<RealVector, double>>();
223
224      //results
225      Results.Add(new Result(IterationsResultName, new IntValue(0)));
226      Results.Add(new Result(EvaluatedSoultionsResultName, new IntValue(Samples.Count)));
227      Results.Add(new Result(BestSolutionResultName, new RealVector(1)));
228      Results.Add(new Result(BestQualityResultName, new DoubleValue(Problem.Maximization ? double.MinValue : double.MaxValue)));
229      Results.Add(new Result(RegressionSolutionResultName, typeof(IRegressionSolution)));
230      var table = new DataTable(QualitiesChartResultName);
231      table.Rows.Add(new DataRow(BestQualitiesRowResultName));
232      table.Rows.Add(new DataRow(WorstQualitiesRowResultName));
233      table.Rows.Add(new DataRow(CurrentQualitiesRowResultName));
234      Results.Add(new Result(QualitiesChartResultName, table));
235      if (BaselineVector != null && BaselineVector.Length == enc.Length) Results.Add(new Result("BaselineValue", new DoubleValue(Evaluate(BaselineVector).Item2)));
236
237
238
239    }
240    protected override void Run(CancellationToken cancellationToken) {
241      //initial samples
242      if (Samples.Count < InitialEvaluations) {
243        var points = InitialSamplingPlan.GetSamples(InitialEvaluations - Samples.Count, Samples.Select(x => x.Item1).ToArray(), (RealVectorEncoding)Problem.Encoding, Random);
244        foreach (var t in points) {
245          try {
246            Samples.Add(Evaluate(t));
247            cancellationToken.ThrowIfCancellationRequested();
248          } finally {
249            Analyze();
250          }
251        }
252      }
253      //adaptive samples
254      for (ResultsIterations = 0; ResultsEvaluations < MaximumEvaluations; ResultsIterations++) {
255        try {
256          ResultsModel = BuildModel(cancellationToken);
257          if (ResultsModel == null) break;
258          cancellationToken.ThrowIfCancellationRequested();
259          for (var i = 0; i < GenerationSize; i++) {
260            var samplepoint = OptimizeInfillProblem(cancellationToken);
261            var sample = Evaluate(samplepoint);
262            Samples.Add(sample);
263            cancellationToken.ThrowIfCancellationRequested();
264          }
265
266        } finally {
267          Analyze();
268        }
269      }
270    }
271
272    #region Eventhandling
273    private void RegisterEventhandlers() {
274      DeregisterEventhandlers();
275      RegressionAlgorithmParameter.ValueChanged += OnModelAlgorithmChanged;
276      InfillOptimizationAlgorithmParameter.ValueChanged += OnInfillOptimizationAlgorithmChanged;
277      InfillOptimizationAlgorithm.ProblemChanged += InfillOptimizationProblemChanged;
278      InfillCriterionParameter.ValueChanged += InfillCriterionChanged;
279      InitialSamplesParameter.ToStringChanged += OnInitialSamplesChanged;
280
281
282    }
283    private void DeregisterEventhandlers() {
284      RegressionAlgorithmParameter.ValueChanged -= OnModelAlgorithmChanged;
285      InfillOptimizationAlgorithmParameter.ValueChanged -= OnInfillOptimizationAlgorithmChanged;
286      InfillOptimizationAlgorithm.ProblemChanged -= InfillOptimizationProblemChanged;
287      InfillCriterionParameter.ValueChanged -= InfillCriterionChanged;
288      InitialSamplesParameter.ToStringChanged -= OnInitialSamplesChanged;
289    }
290    private void OnInfillOptimizationAlgorithmChanged(object sender, EventArgs args) {
291      SetInfillProblem();
292      InfillOptimizationAlgorithm.ProblemChanged += InfillOptimizationProblemChanged;
293    }
294    private void InfillOptimizationProblemChanged(object sender, EventArgs e) {
295      InfillOptimizationAlgorithm.ProblemChanged -= InfillOptimizationProblemChanged;
296      SetInfillProblem();
297      InfillOptimizationAlgorithm.ProblemChanged += InfillOptimizationProblemChanged;
298    }
299    private void InfillCriterionChanged(object sender, EventArgs e) {
300      var infillProblem = InfillOptimizationAlgorithm.Problem as InfillProblem;
301      if (infillProblem == null) throw new ArgumentException("InfillOptimizationAlgorithm has no InfillProblem. Troubles with Eventhandling?");
302      infillProblem.InfillCriterion = InfillCriterion;
303    }
304    private void OnModelAlgorithmChanged(object sender, EventArgs args) {
305      RegressionAlgorithm.Problem = new RegressionProblem();
306    }
307    private void OnInitialSamplesChanged(object sender, EventArgs args) { }
308    protected override void OnExecutionTimeChanged() {
309      base.OnExecutionTimeChanged();
310      if (CancellationTokenSource == null) return;
311      if (MaximumRuntime == -1) return;
312      if (ExecutionTime.TotalSeconds > MaximumRuntime) CancellationTokenSource.Cancel();
313    }
314    public override void Pause() {
315      if (InfillOptimizationAlgorithm.ExecutionState == ExecutionState.Started || InfillOptimizationAlgorithm.ExecutionState == ExecutionState.Paused) InfillOptimizationAlgorithm.Stop();
316      if (RegressionAlgorithm.ExecutionState == ExecutionState.Started || RegressionAlgorithm.ExecutionState == ExecutionState.Paused) RegressionAlgorithm.Stop();
317      base.Pause();
318    }
319    public override void Stop() {
320      if (InfillOptimizationAlgorithm.ExecutionState == ExecutionState.Started || InfillOptimizationAlgorithm.ExecutionState == ExecutionState.Paused) InfillOptimizationAlgorithm.Stop();
321      if (RegressionAlgorithm.ExecutionState == ExecutionState.Started || RegressionAlgorithm.ExecutionState == ExecutionState.Paused) RegressionAlgorithm.Stop();
322      base.Stop();
323    }
324    #endregion
325
326    #region helpers
327    private IRegressionSolution BuildModel(CancellationToken cancellationToken) {
328      var dataset = EgoUtilities.GetDataSet(DataSamples.ToList(), RemoveDuplicates);
329      var problemdata = new RegressionProblemData(dataset, dataset.VariableNames.Where(x => !x.Equals("output")), "output");
330      problemdata.TrainingPartition.Start = 0;
331      problemdata.TrainingPartition.End = dataset.Rows;
332      problemdata.TestPartition.Start = dataset.Rows;
333      problemdata.TestPartition.End = dataset.Rows;
334
335      //train
336      var problem = (RegressionProblem)RegressionAlgorithm.Problem;
337      problem.ProblemDataParameter.Value = problemdata;
338      var i = 0;
339      IRegressionSolution solution = null;
340
341      while (solution == null && i++ < 100) {
342        var results = EgoUtilities.SyncRunSubAlgorithm(RegressionAlgorithm, Random.Next(int.MaxValue), cancellationToken);
343        solution = results.Select(x => x.Value).OfType<IRegressionSolution>().SingleOrDefault();
344        cancellationToken.ThrowIfCancellationRequested();
345      }
346
347      //try creating a model with old hyperparameters and new dataset;
348      var gp = RegressionAlgorithm as GaussianProcessRegression;
349      var oldmodel = ResultsModel as GaussianProcessRegressionSolution;
350      if (gp != null && oldmodel != null) {
351        var n = Samples.First().Item1.Length;
352        var mean = (IMeanFunction)oldmodel.Model.MeanFunction.Clone();
353        var cov = (ICovarianceFunction)oldmodel.Model.CovarianceFunction.Clone();
354        if (mean.GetNumberOfParameters(n) != 0 || cov.GetNumberOfParameters(n) != 0) throw new ArgumentException("DEBUG: assumption about fixed paramters wrong");
355        var noise = 0.0;
356        double[] hyp = { noise };
357        try {
358          var model = new GaussianProcessModel(problemdata.Dataset, problemdata.TargetVariable,
359            problemdata.AllowedInputVariables, problemdata.TrainingIndices, hyp, mean, cov);
360          model.FixParameters();
361          var sol = new GaussianProcessRegressionSolution(model, problemdata);
362          if (solution == null || solution.TrainingMeanSquaredError > sol.TrainingMeanSquaredError) {
363            solution = sol;
364          }
365        } catch (ArgumentException) { }
366      }
367
368
369      if (!ResultsQualities.Rows.ContainsKey("DEBUG: Degenerates")) ResultsQualities.Rows.Add(new DataRow("DEBUG: Degenerates"));
370      var row = ResultsQualities.Rows["DEBUG: Degenerates"];
371      row.Values.Add(i - 1);
372      if (solution == null) Results.Add(new Result("Status", new StringValue("The Algorithm did not return a Model")));
373      else {
374        if (!ResultsQualities.Rows.ContainsKey("DEBUG: RMSE")) ResultsQualities.Rows.Add(new DataRow("DEBUG: RMSE"));
375        row = ResultsQualities.Rows["DEBUG: RMSE"];
376        row.Values.Add(Math.Sqrt(solution.TrainingMeanSquaredError));
377      }
378
379      RegressionAlgorithm.Runs.Clear();
380      return solution;
381    }
382    private RealVector OptimizeInfillProblem(CancellationToken cancellationToken) {
383      //parameterize and check InfillProblem
384      var infillProblem = InfillOptimizationAlgorithm.Problem as InfillProblem;
385      if (infillProblem == null) throw new ArgumentException("InfillOptimizationAlgorithm does not have an InfillProblem.");
386      if (infillProblem.InfillCriterion != InfillCriterion) throw new ArgumentException("InfillCiriterion for Problem is not correctly set.");
387      var enc = Problem.Encoding as RealVectorEncoding;
388      infillProblem.Encoding.Bounds = enc.Bounds;
389      infillProblem.Encoding.Length = enc.Length;
390      infillProblem.Initialize(ResultsModel, Problem.Maximization);
391
392
393
394      RealVector bestVector = null;
395      var bestValue = infillProblem.Maximization ? double.NegativeInfinity : double.PositiveInfinity;
396      for (var i = 0; i < InfillOptimizationRestarts; i++) {
397        //optimize
398        var res = EgoUtilities.SyncRunSubAlgorithm(InfillOptimizationAlgorithm, Random.Next(int.MaxValue), cancellationToken);
399        cancellationToken.ThrowIfCancellationRequested();
400        //extract results
401        if (!res.ContainsKey(InfillProblem.BestInfillSolutionResultName)) throw new ArgumentException("The InfillOptimizationAlgorithm did not return a best solution");
402        var v = res[InfillProblem.BestInfillSolutionResultName].Value as RealVector;
403        if (!res.ContainsKey(InfillProblem.BestInfillQualityResultName)) throw new ArgumentException("The InfillOptimizationAlgorithm did not return a best quality");
404        var d = res[InfillProblem.BestInfillQualityResultName].Value as DoubleValue;
405        if (d == null || v == null) throw new ArgumentException("The InfillOptimizationAlgorithm did not return the expected result types");
406        //check for improvement
407        if (infillProblem.Maximization != d.Value > bestValue) continue;
408        bestValue = d.Value;
409        bestVector = v;
410      }
411      InfillOptimizationAlgorithm.Runs.Clear();
412      return bestVector;
413    }
414
415    private void Analyze() {
416      ResultsEvaluations = Samples.Count;
417      var max = Samples.ArgMax(x => x.Item2);
418      var min = Samples.ArgMin(x => x.Item2);
419      var best = Samples[Problem.Maximization ? max : min];
420      ResultsBestQuality = best.Item2;
421      ResultsBestSolution = best.Item1;
422      ResultsQualitiesBest.Values.Add(ResultsBestQuality);
423      ResultsQualitiesIteration.Values.Add(Samples[Samples.Count - 1].Item2);
424      ResultsQualitiesWorst.Values.Add(Samples[Problem.Maximization ? min : max].Item2);
425      Problem.Analyze(Samples.Select(x => GetIndividual(x.Item1)).ToArray(), Samples.Select(x => x.Item2).ToArray(), Results, Random);
426      if (Samples.Count != 0 && Samples[0].Item1.Length == 2) AnalyzeSampleDistribution();
427      AnalyzePredictionCorrelation();
428    }
429
430    private void AnalyzeSampleDistribution() {
431      const string plotname = "DEBUG:Sample Distribution";
432      const string rowInit = "Initial Samples";
433      const string rowAll = "All Samples";
434      if (!Results.ContainsKey(plotname)) Results.Add(new Result(plotname, new ScatterPlot()));
435      var plot = (ScatterPlot)Results[plotname].Value;
436      if (!plot.Rows.ContainsKey(rowInit) && InitialSamples != null && InitialSamples.Count > 0)
437        plot.Rows.Add(new ScatterPlotDataRow(rowInit, "samples from inital file (already evaulated)", InitialSamples.Select(x => new Point2D<double>(x.Item1[0], x.Item1[1]))));
438      if (!plot.Rows.ContainsKey(rowAll)) plot.Rows.Add(new ScatterPlotDataRow(rowAll, "All samples", new Point2D<double>[0]));
439      else { plot.Rows[rowAll].Points.Clear(); }
440      plot.Rows[rowAll].Points.AddRange(Samples.Select(x => new Point2D<double>(x.Item1[0], x.Item1[1])));
441    }
442
443    private void AnalyzePredictionCorrelation() {
444      const string plotName = "Prediction";
445      const string rowName = "Samples";
446      const string lastrowName = "Last Sample";
447      if (!Results.ContainsKey(plotName)) Results.Add(new Result(plotName, new ScatterPlot()));
448      var plot = (ScatterPlot)Results[plotName].Value;
449      if (!plot.Rows.ContainsKey(rowName)) plot.Rows.Add(new ScatterPlotDataRow(rowName, rowName, new List<Point2D<double>>()));
450      if (!plot.Rows.ContainsKey(lastrowName)) plot.Rows.Add(new ScatterPlotDataRow(lastrowName, lastrowName, new List<Point2D<double>>()));
451      var p = Samples[Samples.Count - 1];
452      if (ResultsModel != null) plot.Rows[rowName].Points.Add(new Point2D<double>(ResultsModel.Model.GetEstimation(p.Item1), p.Item2, p.Item1));
453      plot.VisualProperties.YAxisTitle = "True Objective Value";
454      plot.VisualProperties.XAxisTitle = "Predicted Objective Value";
455
456    }
457
458    private Individual GetIndividual(RealVector r) {
459      var scope = new Scope();
460      scope.Variables.Add(new Variable(Problem.Encoding.Name, r));
461      return new SingleEncodingIndividual(Problem.Encoding, scope);
462    }
463    private Tuple<RealVector, double> Evaluate(RealVector point) {
464      return new Tuple<RealVector, double>(point, Problem.Evaluate(GetIndividual(point), Random));
465    }
466
467    private void SetInfillProblem() {
468      InfillOptimizationAlgorithm.Problem = new InfillProblem { InfillCriterion = InfillCriterion };
469    }
470    #endregion
471  }
472}
Note: See TracBrowser for help on using the repository browser.