Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 16949 was 16949, checked in by abeham, 5 years ago

#2521: Adapted test function problems to new real vector problem

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