Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Problems.MultiObjectiveTestFunctions/HeuristicLab.Problems.MultiObjectiveTestFunctions/3.3/MultiObjectiveTestFunctionProblem.cs @ 13620

Last change on this file since 13620 was 13620, checked in by bwerth, 8 years ago

#1087 regorganized testfunctions, added view for qualities

File size: 12.0 KB
Line 
1using System;
2using System.Collections.Generic;
3using HeuristicLab.Common;
4using HeuristicLab.Core;
5using HeuristicLab.Data;
6using HeuristicLab.Encodings.RealVectorEncoding;
7using HeuristicLab.Optimization;
8using HeuristicLab.Parameters;
9using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
10using HeuristicLab.Problems.Instances;
11using HeuristicLab.Problems.MultiObjectiveTestFunctions;
12using HeuristicLab.Problems.MultiObjectiveTestFunctions.Drawings;
13
14namespace HeuristicLab.Problems.MultiObjectiveTestFunction {
15  [StorableClass]
16  public class MultiObjectiveTestFunctionProblem : MultiObjectiveBasicProblem<RealVectorEncoding>, IProblemInstanceConsumer<MOTFData> {
17
18
19    //TODO update of Maximisatzion when SolutionSize or TestFunction changes
20    public override bool[] Maximization {
21      get {
22        return Parameters.ContainsKey("TestFunction") ? TestFunction.Maximization(Objectives) : new bool[2];
23      }
24    }
25
26    #region Parameter Properties
27
28    /// <summary>
29    /// The dimensionality of the solution candidates
30    /// </summary>
31    private IFixedValueParameter<IntValue> ProblemSizeParameter {
32      get { return (IFixedValueParameter<IntValue>)Parameters["ProblemSize"]; }
33    }
34
35    /// <summary>
36    /// The number of objectives that are to be optimized
37    /// </summary>
38    private IFixedValueParameter<IntValue> SolutionSizeParameter {
39      get { return (IFixedValueParameter<IntValue>)Parameters["SolutionSize"]; }
40    }
41
42    /// <summary>
43    /// The bounds for the entries of the solution candidate
44    /// </summary>
45    private IValueParameter<DoubleMatrix> BoundsParameter {
46      get { return (IValueParameter<DoubleMatrix>)Parameters["Bounds"]; }
47    }
48
49    /// <summary>
50    /// The testfunction
51    /// </summary>
52    public IValueParameter<IMultiObjectiveTestFunction> TestFunctionParameter {
53      get { return (IValueParameter<IMultiObjectiveTestFunction>)Parameters["TestFunction"]; }
54    }
55    #endregion
56
57    #region Properties
58    public int SolutionLength {
59      get { return ProblemSizeParameter.Value.Value; }
60      set { ProblemSizeParameter.Value.Value = value; }
61    }
62    public int Objectives {
63      get { return SolutionSizeParameter.Value.Value; }
64      set { SolutionSizeParameter.Value.Value = value; }
65    }
66    public DoubleMatrix Bounds {
67      get { return BoundsParameter.Value; }
68      set { BoundsParameter.Value = value; }
69    }
70    public IMultiObjectiveTestFunction TestFunction {
71      get { return TestFunctionParameter.Value; }
72      set { TestFunctionParameter.Value = value; }
73    }
74    #endregion
75
76    public override void Analyze(Individual[] individuals, double[][] qualities, ResultCollection results, IRandom random) {
77      base.Analyze(individuals, qualities, results, random);
78      //if (qualities[0].Length != 2) { throw new Exception(); }
79
80
81
82
83      IEnumerable<double[]> opf = null;
84      try {
85        opf = TestFunction.OptimalParetoFront(Objectives);
86
87        //Genearational Distance
88        if (!results.ContainsKey("GenerationalDistance")) results.Add(new Result("GenerationalDistance", typeof(DoubleValue)));
89        GenerationalDistance gd = new GenerationalDistance(1);
90        results["GenerationalDistance"].Value = new DoubleValue(gd.Compare(qualities, opf));
91
92        //Inverted Generational Distance
93        if (!results.ContainsKey("InvertedGenerationalDistance")) results.Add(new Result("InvertedGenerationalDistance", typeof(DoubleValue)));
94        InvertedGenerationalDistance igd = new InvertedGenerationalDistance(1);
95        results["InvertedGenerationalDistance"].Value = new DoubleValue(igd.Compare(qualities, opf));
96
97
98      }
99      catch (NotImplementedException) { } // only do this if the optimal Front is known
100
101
102
103      //Graphical analysis
104      if (!results.ContainsKey("Front")) results.Add(new Result("Front", typeof(IMOQualities)));
105      results["Front"].Value = new IMOSolution(qualities, individuals, opf, Objectives);
106
107
108      //Hypervolume analysis
109      if (!results.ContainsKey("Hypervolume")) results.Add(new Result("Hypervolume", typeof(DoubleValue)));
110      IEnumerable<double[]> front = NonDominatedSelect.selectNonDominatedVectors(qualities, Maximization, true);
111      if (!results.ContainsKey("BestKnownHypervolume")) results.Add(new Result("BestKnownHypervolume", typeof(DoubleValue)));
112      if (!results.ContainsKey("Absolute Distance to BestKnownHypervolume")) results.Add(new Result("Absolute Distance to BestKnownHypervolume", typeof(DoubleValue)));
113
114
115      if (Objectives == 2) { //Hypervolume analysis only with 2 objectives for now
116        Hypervolume comp = new Hypervolume(TestFunction.ReferencePoint(Objectives), Maximization);
117        try {
118          double hv = comp.GetHypervolume(front);
119          results["Hypervolume"].Value = new DoubleValue(hv);
120          double best; double diff;
121          if (TestFunction.BestKnownHypervolume(Objectives) > 0) {   // if best HV is known at all
122            best = TestFunction.BestKnownHypervolume(Objectives);
123            diff = best - hv;
124            if (diff < 0) {  //replace best known Hypervolume
125              diff = 0;
126              best = hv;
127            }
128          } else {  //initalize best known Hypervolume
129            best = hv;
130            diff = 0;
131          }
132
133          results["BestKnownHypervolume"].Value = new DoubleValue(best);
134          results["Absolute Distance to BestKnownHypervolume"].Value = new DoubleValue(diff);
135
136        }
137        catch (ArgumentException) {
138          results["Hypervolume"].Value = new DoubleValue(Double.NaN);
139        }
140
141      }
142      //Experimental HV
143      if(Objectives != 2) {
144        FastHypervolume fcomp = new FastHypervolume(TestFunction.ReferencePoint(Objectives), Maximization);
145        try {
146          double hv = fcomp.GetHypervolume(front, TestFunction.Bounds(Objectives));
147          results["Hypervolume"].Value = new DoubleValue(hv);
148          double best; double diff;
149          if (TestFunction.BestKnownHypervolume(Objectives) > 0) {   // if best HV is known at all
150            best = TestFunction.BestKnownHypervolume(Objectives);
151            diff = best - hv;
152            if (diff < 0) {  //replace best known Hypervolume
153              diff = 0;
154              best = hv;
155            }
156          } else {  //initalize best known Hypervolume
157            best = hv;
158            diff = 0;
159          }
160
161          results["BestKnownHypervolume"].Value = new DoubleValue(best);
162          results["Absolute Distance to BestKnownHypervolume"].Value = new DoubleValue(diff);
163        }
164        catch (ArgumentException) {
165          results["Hypervolume"].Value = new DoubleValue(Double.NaN);
166        }
167      }
168
169
170      //Spacing analysis
171      if (!results.ContainsKey("Spacing")) results.Add(new Result("Spacing", typeof(DoubleValue)));
172      Spacing s = new Spacing();
173      results["Spacing"].Value = new DoubleValue(s.Get(qualities));
174
175      //Crowding
176      if (!results.ContainsKey("Crowding")) results.Add(new Result("Crowding", typeof(DoubleValue)));
177      Crowding c = new Crowding(TestFunction.Bounds(Objectives));
178      results["Crowding"].Value = new DoubleValue(c.Get(qualities));
179
180
181
182    }
183
184    [StorableConstructor]
185    private MultiObjectiveTestFunctionProblem(bool deserializing) : base(deserializing) { }
186    private MultiObjectiveTestFunctionProblem(MultiObjectiveTestFunctionProblem original, Cloner cloner)
187      : base(original, cloner) {
188      RegisterEventHandlers();
189    }
190    public MultiObjectiveTestFunctionProblem()
191      : base() {
192      Parameters.Add(new FixedValueParameter<IntValue>("ProblemSize", "The dimensionality of the problem instance (number of variables in the function).", new IntValue(2)));
193      Parameters.Add(new FixedValueParameter<IntValue>("SolutionSize", "The dimensionality of the solution vector (number of objectives).", new IntValue(2)));
194      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[,] { { -4, 4 } })));
195      Parameters.Add(new ValueParameter<IMultiObjectiveTestFunction>("TestFunction", "The function that is to be optimized.", new Fonseca()));
196
197      Encoding.LengthParameter = ProblemSizeParameter;
198      Encoding.BoundsParameter = BoundsParameter;
199
200      InitializeOperators();
201      RegisterEventHandlers();
202    }
203    public override IDeepCloneable Clone(Cloner cloner) {
204      return new MultiObjectiveTestFunctionProblem(this, cloner);
205    }
206    [StorableHook(HookType.AfterDeserialization)]
207    private void AfterDeserialization() {
208      RegisterEventHandlers();
209    }
210
211    private void RegisterEventHandlers() {
212      TestFunctionParameter.ValueChanged += TestFunctionParameterOnValueChanged;
213      ProblemSizeParameter.Value.ValueChanged += ProblemSizeOnValueChanged;
214      SolutionSizeParameter.Value.ValueChanged += SolutionSizeOnValueChanged;
215      BoundsParameter.ValueChanged += BoundsParameterOnValueChanged;
216    }
217
218    public double[] Evaluate(RealVector individual, IRandom random) {
219      return TestFunction.Evaluate(individual, Objectives);
220    }
221
222    public override double[] Evaluate(Individual individual, IRandom random) {
223      return Evaluate(individual.RealVector(), random);
224    }
225
226    public void Load(MOTFData data) {
227      TestFunction = data.Evaluator;
228    }
229
230    #region Events
231    protected override void OnEncodingChanged() {
232      base.OnEncodingChanged();
233      Parameterize();
234    }
235    protected override void OnEvaluatorChanged() {
236      base.OnEvaluatorChanged();
237      Parameterize();
238    }
239
240    private void TestFunctionParameterOnValueChanged(object sender, EventArgs eventArgs) {
241      var problemSizeChange = SolutionLength < TestFunction.MinimumSolutionLength
242                              || SolutionLength > TestFunction.MaximumSolutionLength;
243      if (problemSizeChange) {
244        SolutionLength = Math.Max(TestFunction.MinimumSolutionLength, Math.Min(SolutionLength, TestFunction.MaximumSolutionLength));
245      }
246
247      var solutionSizeChange = Objectives < TestFunction.MinimumObjectives
248                              || Objectives > TestFunction.MaximumObjectives;
249      if (solutionSizeChange) {
250        SolutionLength = Math.Max(TestFunction.MinimumObjectives, Math.Min(Objectives, TestFunction.MaximumObjectives));
251      }
252      Bounds = (DoubleMatrix)new DoubleMatrix(TestFunction.Bounds(Objectives)).Clone();
253      OnReset();
254    }
255
256    private void ProblemSizeOnValueChanged(object sender, EventArgs eventArgs) {
257      if (SolutionLength < TestFunction.MinimumSolutionLength
258        || SolutionLength > TestFunction.MaximumSolutionLength)
259        SolutionLength = Math.Min(TestFunction.MaximumSolutionLength, Math.Max(TestFunction.MinimumSolutionLength, SolutionLength));
260      if (Objectives < TestFunction.MinimumObjectives
261        || Objectives > TestFunction.MaximumObjectives)
262        Objectives = Math.Min(TestFunction.MaximumObjectives, Math.Max(TestFunction.MinimumObjectives, Objectives));
263    }
264
265    private void SolutionSizeOnValueChanged(object sender, EventArgs eventArgs) {
266      if (Objectives < TestFunction.MinimumObjectives
267        || Objectives > TestFunction.MaximumObjectives)
268        Objectives = Math.Min(TestFunction.MaximumObjectives, Math.Max(TestFunction.MinimumObjectives, Objectives));
269      if (SolutionLength < TestFunction.MinimumSolutionLength
270        || SolutionLength > TestFunction.MaximumSolutionLength)
271        SolutionLength = Math.Min(TestFunction.MaximumSolutionLength, Math.Max(TestFunction.MinimumSolutionLength, SolutionLength));
272    }
273
274    private void BoundsParameterOnValueChanged(object sender, EventArgs eventArgs) {
275      Parameterize();
276    }
277    #endregion
278
279    #region Helpers
280    private void InitializeOperators() {
281      //empty for now
282      Parameterize();
283    }
284
285    private void Parameterize() {
286      //empty for now
287    }
288    #endregion
289  }
290}
291
Note: See TracBrowser for help on using the repository browser.