Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Problems.MultiObjectiveTestFunctions/HeuristicLab.Problems.MultiObjectiveTestFunctions/3.3/Analyzers/NormalizedHypervolumeAnalyzer.cs @ 14030

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

#1087 several fixes according to the reviev comments in comment 31

File size: 6.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 HeuristicLab.Common;
26using HeuristicLab.Core;
27using HeuristicLab.Data;
28using HeuristicLab.Optimization;
29using HeuristicLab.Parameters;
30using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
31
32namespace HeuristicLab.Problems.MultiObjectiveTestFunctions {
33  [StorableClass]
34  [Item("GenerationalDistanceAnalyzer", "Computes the enclosed Hypervolume between the current front and a given reference Point")]
35  public class NormalizedHypervolumeAnalyzer : MOTFAnalyzer {
36    [StorableHook(HookType.AfterDeserialization)]
37    private void AfterDeserialization() {
38    }
39    [StorableConstructor]
40    protected NormalizedHypervolumeAnalyzer(bool deserializing) : base(deserializing) { }
41    public NormalizedHypervolumeAnalyzer(NormalizedHypervolumeAnalyzer original, Cloner cloner) : base(original, cloner) { }
42    public override IDeepCloneable Clone(Cloner cloner) {
43      return new NormalizedHypervolumeAnalyzer(this, cloner);
44    }
45
46
47    #region Names
48    private const string bestKnownFront = "BestKnownFront Zitzler";
49    private const string resultsHV = "NormalizedHypervolume";
50    private const string resultsDist = "Absolute Distance to Normalized BestKnownHypervolume";
51
52    private const string bestknownHV = "NormalizedBestKnownHyperVolume";
53    #endregion
54
55    #region parameters
56    public IValueParameter<DoubleMatrix> OptimalFrontParameter {
57      get {
58        return (IValueParameter<DoubleMatrix>)Parameters[bestKnownFront];
59      }
60    }
61
62    public IValueParameter<DoubleValue> BestKnownHyperVolumeParameter {
63      get {
64        return (IValueParameter<DoubleValue>)Parameters[bestknownHV];
65      }
66      set {
67        Parameters[bestknownHV].ActualValue = value;
68      }
69    }
70    #endregion
71
72    public NormalizedHypervolumeAnalyzer() {
73      if (!Parameters.ContainsKey(bestKnownFront)) Parameters.Add(new ValueParameter<DoubleMatrix>(bestKnownFront, "The true / best known pareto front"));
74      if (!Parameters.ContainsKey(bestknownHV)) Parameters.Add(new ValueParameter<DoubleValue>(bestknownHV, "The currently best known hypervolume"));
75    }
76
77    private void RegisterEventHandlers() {
78      OptimalFrontParameter.ValueChanged += OptimalFrontParameterOnValueChanged;
79    }
80
81    private void OptimalFrontParameterOnValueChanged(object sender, EventArgs e) {
82      BestKnownHyperVolumeParameter.Value = new DoubleValue(0);
83    }
84
85    public override void Analyze(Individual[] individuals, double[][] qualities, ResultCollection results) {
86      if (qualities == null || qualities.Length < 1) return;
87      int objectives = qualities[0].Length;
88      double best = BestKnownHyperVolumeParameter.Value.Value;
89      if (OptimalFrontParameter.Value == null || OptimalFrontParameter.Value.Rows < 1 || OptimalFrontParameter.Value.Columns != qualities[0].Length) {
90        return; // too pareto front nonexistant or with wrong number of dimensions
91      }
92
93      IEnumerable<double[]> front = NonDominatedSelect.selectNonDominatedVectors(qualities, TestFunctionParameter.ActualValue.Maximization(objectives), true);
94
95      if (!results.ContainsKey(resultsHV)) results.Add(new Result(resultsHV, typeof(DoubleValue)));
96      if (!results.ContainsKey(resultsDist)) results.Add(new Result(resultsDist, typeof(DoubleValue)));
97      if (!results.ContainsKey(bestknownHV)) results.Add(new Result(bestknownHV, typeof(DoubleValue)));
98      else {
99        DoubleValue dv = (DoubleValue)(results[bestknownHV].Value);
100        best = dv.Value;
101      }
102
103      bool[] maximization = TestFunctionParameter.ActualValue.Maximization(objectives);
104      double[] invPoint = GetBestPoint(OptimalFrontParameter.Value, maximization);
105      double[] refPoint = GetWorstPoint(OptimalFrontParameter.Value, maximization);
106      double normalization = Hypervolume.Calculate(new double[][] { invPoint }, refPoint, maximization);
107      double hv = front.Any() ? Hypervolume.Calculate(front, refPoint, maximization) / normalization : 0;
108
109      if (Double.IsNaN(best)) best = hv; else best = Math.Max(best, hv);
110      double diff;
111      diff = best - hv;
112      if (diff == 0) {
113        BestKnownFrontParameter.ActualValue = new DoubleMatrix(MultiObjectiveTestFunctionProblem.To2D(qualities));
114      }
115
116      results[resultsHV].Value = new DoubleValue(hv);
117      results[resultsDist].Value = new DoubleValue(diff);
118      results[bestknownHV].Value = new DoubleValue(best);
119
120    }
121
122    private double[] GetWorstPoint(DoubleMatrix value, bool[] maximization) {
123      bool[] invMax = new bool[maximization.Length];
124      int i = 0;
125      foreach (bool b in maximization) {
126        invMax[i++] = !b;
127      }
128      return GetBestPoint(value, invMax);
129    }
130
131    private double[] GetBestPoint(DoubleMatrix value, bool[] maximization) {
132      double[] res = new double[maximization.Length];
133      for (int i = 0; i < maximization.Length; i++) {
134        res[i] = maximization[i] ? Double.MinValue : Double.MaxValue;
135      }
136
137      for (int r = 0; r < value.Rows; r++) {
138        for (int c = 0; c < maximization.Length; c++) {
139          res[c] = maximization[c] ? Math.Max(res[c], value[r, c]) : Math.Min(res[c], value[r, c]);
140        }
141      }
142      return res;
143    }
144  }
145}
Note: See TracBrowser for help on using the repository browser.