Free cookie consent management tool by TermsFeed Policy Generator

source: branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions/3.3/SingleObjectiveTestFunctionProblem.cs @ 17382

Last change on this file since 17382 was 17382, checked in by mkommend, 4 years ago

#2521: Refactored single-objective problems to use EvaluationResult instead of double as return type from Evaluate.

File size: 11.7 KB
RevLine 
[3150]1#region License Information
2/* HeuristicLab
[17226]3 * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
[3150]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
[9980]22using System;
23using System.Collections.Generic;
24using System.Linq;
[17320]25using System.Threading;
[16949]26using HEAL.Attic;
[8720]27using HeuristicLab.Analysis;
[3150]28using HeuristicLab.Common;
29using HeuristicLab.Core;
30using HeuristicLab.Data;
31using HeuristicLab.Encodings.RealVectorEncoding;
32using HeuristicLab.Optimization;
33using HeuristicLab.Parameters;
[9980]34using HeuristicLab.Problems.Instances;
[3150]35
[3170]36namespace HeuristicLab.Problems.TestFunctions {
[12504]37  [Item("Test Function (single-objective)", "Test function with real valued inputs and a single objective.")]
[16723]38  [StorableType("F0AB7236-2C9B-49DC-9D4F-A3558FD9E992")]
[12504]39  [Creatable(CreatableAttribute.Categories.Problems, Priority = 90)]
[16949]40  public sealed class SingleObjectiveTestFunctionProblem : RealVectorProblem,
[13403]41    IProblemInstanceConsumer<SOTFData> {
[4419]42
[3150]43    #region Parameter Properties
[13403]44    private IFixedValueParameter<IntValue> ProblemSizeParameter {
45      get { return (IFixedValueParameter<IntValue>)Parameters["ProblemSize"]; }
[3150]46    }
[13403]47    private IValueParameter<DoubleMatrix> BoundsParameter {
48      get { return (IValueParameter<DoubleMatrix>)Parameters["Bounds"]; }
[3150]49    }
[3781]50    public OptionalValueParameter<RealVector> BestKnownSolutionParameter {
51      get { return (OptionalValueParameter<RealVector>)Parameters["BestKnownSolution"]; }
52    }
[13403]53    public IValueParameter<ISingleObjectiveTestFunction> TestFunctionParameter {
54      get { return (IValueParameter<ISingleObjectiveTestFunction>)Parameters["TestFunction"]; }
55    }
[3150]56    #endregion
57
58    #region Properties
[13403]59    public int ProblemSize {
60      get { return ProblemSizeParameter.Value.Value; }
61      set { ProblemSizeParameter.Value.Value = value; }
62    }
[3150]63    public DoubleMatrix Bounds {
64      get { return BoundsParameter.Value; }
65      set { BoundsParameter.Value = value; }
66    }
[13403]67    public ISingleObjectiveTestFunction TestFunction {
68      get { return TestFunctionParameter.Value; }
69      set { TestFunctionParameter.Value = value; }
[3150]70    }
71    #endregion
72
73    [StorableConstructor]
[16723]74    private SingleObjectiveTestFunctionProblem(StorableConstructorFlag _) : base(_) { }
[4722]75    private SingleObjectiveTestFunctionProblem(SingleObjectiveTestFunctionProblem original, Cloner cloner)
76      : base(original, cloner) {
[7351]77      RegisterEventHandlers();
[4722]78    }
[3170]79    public SingleObjectiveTestFunctionProblem()
[13403]80      : base(new RealVectorEncoding("Point")) {
81      Parameters.Add(new FixedValueParameter<IntValue>("ProblemSize", "The dimensionality of the problem instance (number of variables in the function).", new IntValue(2)));
82      Parameters.Add(new ValueParameter<DoubleMatrix>("Bounds", "The bounds of the solution given as either one line for all variables or a line for each variable. The first column specifies lower bound, the second upper bound.", new DoubleMatrix(new double[,] { { -100, 100 } })));
[3781]83      Parameters.Add(new OptionalValueParameter<RealVector>("BestKnownSolution", "The best known solution for this test function instance."));
[13403]84      Parameters.Add(new ValueParameter<ISingleObjectiveTestFunction>("TestFunction", "The function that is to be optimized.", new Ackley()));
[17270]85      Maximization = TestFunction.Maximization;
[3150]86
[13403]87      Encoding.LengthParameter = ProblemSizeParameter;
88      Encoding.BoundsParameter = BoundsParameter;
89      BestKnownQuality = TestFunction.BestKnownQuality;
[6939]90
[4098]91      InitializeOperators();
[7351]92      RegisterEventHandlers();
[3150]93    }
94
95    public override IDeepCloneable Clone(Cloner cloner) {
[4722]96      return new SingleObjectiveTestFunctionProblem(this, cloner);
[3150]97    }
98
[13403]99    [StorableHook(HookType.AfterDeserialization)]
100    private void AfterDeserialization() {
101      RegisterEventHandlers();
102    }
103
104    private void RegisterEventHandlers() {
105      Evaluator.QualityParameter.ActualNameChanged += Evaluator_QualityParameter_ActualNameChanged;
106      TestFunctionParameter.ValueChanged += TestFunctionParameterOnValueChanged;
107      ProblemSizeParameter.Value.ValueChanged += ProblemSizeOnValueChanged;
108      BoundsParameter.ValueChanged += BoundsParameterOnValueChanged;
109    }
110
[17382]111    public override ISingleObjectiveEvaluationResult Evaluate(RealVector individual, IRandom random, CancellationToken cancellationToken) {
112      var quality = TestFunction.Evaluate(individual);
113      return new SingleObjectiveEvaluationResult(quality);
[13403]114    }
115
[16949]116    public override void Analyze(RealVector[] realVectors, double[] qualities, ResultCollection results, IRandom random) {
[16950]117      var best = GetBestSolution(realVectors, qualities);
[16949]118
119      DoubleValue bestKnownQuality = BestKnownQualityParameter.Value;
[16950]120      RealVector bestKnownSolution = null;
121      var bestKnownUpdate = bestKnownQuality == null || IsBetter(best.Item2, bestKnownQuality.Value);
122      if (bestKnownUpdate) {
123        if (bestKnownQuality != null) bestKnownQuality.Value = best.Item2;
124        else BestKnownQualityParameter.Value = bestKnownQuality = new DoubleValue(best.Item2);
125        BestKnownSolutionParameter.Value = bestKnownSolution = (RealVector)best.Item1.Clone();
126      }
127
[16949]128      SingleObjectiveTestFunctionSolution solution = null;
129      if (results.TryGetValue("Best Solution", out var res)) {
130        solution = (SingleObjectiveTestFunctionSolution)res.Value;
[16950]131        if (IsBetter(best.Item2, solution.BestQuality.Value)) {
132          solution.BestRealVector = (RealVector)best.Item1.Clone();
133          solution.BestQuality = new DoubleValue(best.Item2);
134        }
135      } else {
136        solution = new SingleObjectiveTestFunctionSolution((RealVector)best.Item1.Clone(),
137                                                           new DoubleValue(best.Item2),
138                                                           TestFunctionParameter.Value) {
139          BestKnownRealVector = bestKnownSolution,
140          Bounds = BoundsParameter.Value
141        };
[16949]142        results.Add(new Result("Best Solution", solution));
143      }
[16950]144      if (best.Item1.Length == 2) solution.Population = new ItemArray<RealVector>(realVectors.Select(x => (RealVector)x.Clone()));
145      if (bestKnownUpdate) solution.BestKnownRealVector = bestKnownSolution;
[16949]146    }
147
[3150]148    #region Events
[13403]149    protected override void OnEncodingChanged() {
150      base.OnEncodingChanged();
151      Parameterize();
[3150]152    }
[6938]153    protected override void OnEvaluatorChanged() {
154      base.OnEvaluatorChanged();
[13403]155      Evaluator.QualityParameter.ActualNameChanged += Evaluator_QualityParameter_ActualNameChanged;
156      Parameterize();
[3150]157    }
158    private void Evaluator_QualityParameter_ActualNameChanged(object sender, EventArgs e) {
[13403]159      Parameterize();
[3150]160    }
[13403]161    private void TestFunctionParameterOnValueChanged(object sender, EventArgs eventArgs) {
162      var problemSizeChange = ProblemSize < TestFunction.MinimumProblemSize
163                              || ProblemSize > TestFunction.MaximumProblemSize;
164      if (problemSizeChange) {
165        ProblemSize = Math.Max(TestFunction.MinimumProblemSize, Math.Min(ProblemSize, TestFunction.MaximumProblemSize));
[3187]166      }
[13403]167      BestKnownQuality = TestFunction.BestKnownQuality;
168      Bounds = (DoubleMatrix)TestFunction.Bounds.Clone();
169      var bestSolution = TestFunction.GetBestKnownSolution(ProblemSize);
170      BestKnownSolutionParameter.Value = bestSolution;
[17270]171      Maximization = TestFunction.Maximization;
[13403]172
173      OnReset();
[3182]174    }
[13403]175    private void ProblemSizeOnValueChanged(object sender, EventArgs eventArgs) {
176      if (ProblemSize < TestFunction.MinimumProblemSize
177        || ProblemSize > TestFunction.MaximumProblemSize)
178        ProblemSize = Math.Min(TestFunction.MaximumProblemSize, Math.Max(TestFunction.MinimumProblemSize, ProblemSize));
[3318]179    }
[13403]180    private void BoundsParameterOnValueChanged(object sender, EventArgs eventArgs) {
181      Parameterize();
[3318]182    }
[3150]183    #endregion
184
185    #region Helpers
186    private void InitializeOperators() {
[8334]187      Operators.Add(new SingleObjectiveTestFunctionImprovementOperator());
188      Operators.Add(new SingleObjectiveTestFunctionPathRelinker());
189      Operators.Add(new SingleObjectiveTestFunctionSimilarityCalculator());
[16692]190      Operators.Add(new EuclideanSimilarityCalculator());
[13403]191      Operators.Add(new AdditiveMoveEvaluator());
[8334]192
[13403]193      Parameterize();
[3150]194    }
[13403]195
196    private void Parameterize() {
197      var operators = new List<IItem>();
[16949]198      foreach (var op in Operators.OfType<PopulationSimilarityAnalyzer>()) {
199        var calcs = Operators.OfType<ISolutionSimilarityCalculator>().ToArray();
200        op.SimilarityCalculatorParameter.ValidValues.Clear();
201        foreach (var c in calcs) {
202          // TODO: unified encoding parameters
203          c.SolutionVariableName = ((IRealVectorSolutionOperator)Encoding.SolutionCreator).RealVectorParameter.ActualName;
204          c.QualityVariableName = Evaluator.QualityParameter.ActualName;
205          op.SimilarityCalculatorParameter.ValidValues.Add(c);
206        }
[3150]207      }
[9258]208      foreach (var op in Operators.OfType<ISingleObjectiveTestFunctionAdditiveMoveEvaluator>()) {
[13403]209        operators.Add(op);
[3187]210        op.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName;
[6051]211        op.QualityParameter.Hidden = true;
[13403]212        foreach (var movOp in Encoding.Operators.OfType<IRealVectorAdditiveMoveQualityOperator>())
213          movOp.MoveQualityParameter.ActualName = op.MoveQualityParameter.ActualName;
[3187]214      }
[16692]215      foreach (var op in Operators.OfType<IRealVectorParticleCreator>()) {
216        // TODO: unified encoding parameters
217        op.RealVectorParameter.ActualName = ((IRealVectorSolutionOperator)Encoding.SolutionCreator).RealVectorParameter.ActualName;
218        op.RealVectorParameter.Hidden = true;
219        op.BoundsParameter.ActualName = BoundsParameter.Name;
220        op.BoundsParameter.Hidden = true;
221      }
222      foreach (var op in Operators.OfType<IRealVectorParticleUpdater>()) {
223        // TODO: unified encoding parameters
224        op.RealVectorParameter.ActualName = ((IRealVectorSolutionOperator)Encoding.SolutionCreator).RealVectorParameter.ActualName;
225        op.RealVectorParameter.Hidden = true;
226        op.BoundsParameter.ActualName = BoundsParameter.Name;
227        op.BoundsParameter.Hidden = true;
228      }
[9258]229      foreach (var op in Operators.OfType<IRealVectorSwarmUpdater>()) {
[5951]230        op.MaximizationParameter.ActualName = MaximizationParameter.Name;
[6051]231        op.MaximizationParameter.Hidden = true;
[5561]232      }
[9258]233      foreach (var op in Operators.OfType<ISingleObjectiveImprovementOperator>()) {
[13403]234        operators.Add(op);
235        op.SolutionParameter.ActualName = Encoding.Name;
[8334]236        op.SolutionParameter.Hidden = true;
237      }
[13403]238      foreach (var op in Operators.OfType<ITestFunctionSolutionSimilarityCalculator>()) {
239        operators.Add(op);
240        op.SolutionVariableName = Encoding.Name;
[8334]241        op.QualityVariableName = Evaluator.QualityParameter.ActualName;
[13403]242        op.Bounds = Bounds;
[8334]243      }
[13403]244
245      if (operators.Count > 0) Encoding.ConfigureOperators(operators);
[3150]246    }
247    #endregion
[9980]248
249    public void Load(SOTFData data) {
250      Name = data.Name;
251      Description = data.Description;
[13403]252      TestFunction = data.TestFunction;
[9980]253    }
[3150]254  }
255}
Note: See TracBrowser for help on using the repository browser.