Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
04/18/16 10:50:15 (8 years ago)
Author:
bwerth
Message:

#1087 bugfix + additional relative HV calculation added

File:
1 copied

Legend:

Unmodified
Added
Removed
  • branches/HeuristicLab.Problems.MultiObjectiveTestFunctions/HeuristicLab.Problems.MultiObjectiveTestFunctions/3.3/Analyzers/NormalizedHypervolumeAnalyzer.cs

    r13725 r13771  
    3232  [StorableClass]
    3333  [Item("GenerationalDistanceAnalyzer", "Computes the enclosed Hypervolume between the current front and a given reference Point")]
    34   public class HypervolumeAnalyzer : MOTFAnalyzer {
     34  public class NormalizedHypervolumeAnalyzer : MOTFAnalyzer {
    3535    [StorableHook(HookType.AfterDeserialization)]
    3636    private void AfterDeserialization() {
    3737    }
    3838    [StorableConstructor]
    39     protected HypervolumeAnalyzer(bool deserializing) : base(deserializing) { }
    40     public HypervolumeAnalyzer(HypervolumeAnalyzer original, Cloner cloner) : base(original, cloner) { }
     39    protected NormalizedHypervolumeAnalyzer(bool deserializing) : base(deserializing) { }
     40    public NormalizedHypervolumeAnalyzer(NormalizedHypervolumeAnalyzer original, Cloner cloner) : base(original, cloner) { }
    4141    public override IDeepCloneable Clone(Cloner cloner) {
    42       return new HypervolumeAnalyzer(this, cloner);
     42      return new NormalizedHypervolumeAnalyzer(this, cloner);
    4343    }
    4444
    45     public IValueParameter<DoubleArray> ReferencePointParameter {
     45
     46    #region Names
     47    private const string bestKnownFront = "BestKnownFront_2";
     48    private const string resultsHV = "NormalizedHypervolume";
     49    private const string resultsDist = "Absolute Distance to Normalized BestKnownHypervolume";
     50
     51    private const string bestknownHV = "NormalizedBestKnownHyperVolume";
     52    #endregion
     53
     54    #region parameters
     55    public IValueParameter<DoubleMatrix> OptimalFrontParameter {
    4656      get {
    47         return (IValueParameter<DoubleArray>)Parameters["ReferencePoint"];
     57        return (IValueParameter<DoubleMatrix>)Parameters[bestKnownFront];
    4858      }
    4959    }
     
    5161    public IValueParameter<DoubleValue> BestKnownHyperVolumeParameter {
    5262      get {
    53         return (IValueParameter<DoubleValue>)Parameters["BestKnownHyperVolume"];
     63        return (IValueParameter<DoubleValue>)Parameters[bestknownHV];
    5464      }
    5565      set {
    56         Parameters["BestKnownHyperVolume"].ActualValue = value;
     66        Parameters[bestknownHV].ActualValue = value;
    5767      }
    5868    }
     69    #endregion
    5970
    60     public HypervolumeAnalyzer() {
    61       Parameters.Add(new ValueParameter<DoubleArray>("ReferencePoint", "The reference point for hypervolume calculation"));
    62       Parameters.Add(new ValueParameter<DoubleValue>("BestKnownHyperVolume", "The currently best known hypervolume"));
     71    public NormalizedHypervolumeAnalyzer() {
     72      if (!Parameters.ContainsKey(bestKnownFront)) Parameters.Add(new ValueParameter<DoubleMatrix>(bestKnownFront, "The true / best known pareto front"));
     73      if (!Parameters.ContainsKey(bestknownHV)) Parameters.Add(new ValueParameter<DoubleValue>(bestknownHV, "The currently best known hypervolume"));
    6374    }
    6475
    6576    private void RegisterEventHandlers() {
    66       ReferencePointParameter.ValueChanged += ReferencePointParameterOnValueChanged;
     77      OptimalFrontParameter.ValueChanged += OptimalFrontParameterOnValueChanged;
    6778    }
    6879
    69     private void ReferencePointParameterOnValueChanged(object sender, EventArgs e) {
     80    private void OptimalFrontParameterOnValueChanged(object sender, EventArgs e) {
    7081      BestKnownHyperVolumeParameter.Value = new DoubleValue(0);
    7182    }
    7283
    7384    public override void Analyze(Individual[] individuals, double[][] qualities, ResultCollection results) {
    74       if (qualities == null || qualities.Length < 2) return;
     85      if (qualities == null || qualities.Length < 1) return;
    7586      int objectives = qualities[0].Length;
    7687      double best = BestKnownHyperVolumeParameter.Value.Value;
     88      if (OptimalFrontParameter.Value == null || OptimalFrontParameter.Value.Rows < 1 || OptimalFrontParameter.Value.Columns != qualities[0].Length) {
     89        return; // too pareto front nonexistant or with wrong number of dimensions
     90      }
    7791
    7892      double diff;
    7993
    80       if (!results.ContainsKey("Hypervolume")) results.Add(new Result("Hypervolume", typeof(DoubleValue)));
     94      if (!results.ContainsKey(resultsHV)) results.Add(new Result(resultsHV, typeof(DoubleValue)));
    8195      IEnumerable<double[]> front = NonDominatedSelect.selectNonDominatedVectors(qualities, TestFunctionParameter.ActualValue.Maximization(objectives), true);
    82       if (!results.ContainsKey("BestKnownHypervolume")) results.Add(new Result("BestKnownHypervolume", typeof(DoubleValue)));
     96      if (!results.ContainsKey(bestknownHV)) results.Add(new Result(bestknownHV, typeof(DoubleValue)));
    8397      else {
    84         DoubleValue dv = (DoubleValue)(results["BestKnownHypervolume"].Value);
     98        DoubleValue dv = (DoubleValue)(results[bestknownHV].Value);
    8599        best = dv.Value;
    86100      }
    87       if (!results.ContainsKey("Absolute Distance to BestKnownHypervolume")) results.Add(new Result("Absolute Distance to BestKnownHypervolume", typeof(DoubleValue)));
     101      if (!results.ContainsKey(resultsDist)) results.Add(new Result(resultsDist, typeof(DoubleValue)));
    88102
    89103      double hv = Double.NaN;
     104
     105      bool[] maximization = TestFunctionParameter.ActualValue.Maximization(objectives);
     106      double[] invPoint = GetBestPoint(OptimalFrontParameter.Value, maximization);
     107      double[] refPoint = GetWorstPoint(OptimalFrontParameter.Value, maximization);
     108      double normalization = GetHypervolume(refPoint, invPoint);
     109
     110
    90111      try {
    91112        if (objectives == 2) { //Hypervolume analysis only with 2 objectives for now
    92           hv = Hypervolume.Calculate(front, ReferencePointParameter.Value, TestFunctionParameter.ActualValue.Maximization(objectives));
    93         } else if (Array.TrueForAll(TestFunctionParameter.ActualValue.Maximization(objectives), x => !x)) {
    94           hv = MultiDimensionalHypervolume.Calculate(front, ReferencePointParameter.Value);
     113          hv = Hypervolume.Calculate(front, refPoint, maximization);
     114        } else if (Array.TrueForAll(maximization, x => !x)) {
     115          hv = MultiDimensionalHypervolume.Calculate(front, refPoint);
    95116        }
    96117      }
     
    98119
    99120      }
     121
     122      hv /= normalization;
    100123
    101124      if (best < 0) {
     
    109132      }
    110133
    111       results["Hypervolume"].Value = new DoubleValue(hv);
    112       results["Absolute Distance to BestKnownHypervolume"].Value = new DoubleValue(diff);
    113       results["BestKnownHypervolume"].Value = new DoubleValue(best);
     134      results[resultsHV].Value = new DoubleValue(hv);
     135      results[resultsDist].Value = new DoubleValue(diff);
     136      results[bestknownHV].Value = new DoubleValue(best);
    114137
     138    }
     139
     140    private double GetHypervolume(double[] refPoint, double[] invPoint) {
     141      if (refPoint.Length == 0) return 0;
     142      double hv = 1;
     143      for (int i = 0; i < refPoint.Length; i++) {
     144        hv *= Math.Abs(refPoint[i] - invPoint[i]);
     145      }
     146      return hv;
     147    }
     148
     149    private double[] GetWorstPoint(DoubleMatrix value, bool[] maximization) {
     150      bool[] invMax = new bool[maximization.Length];
     151      int i = 0;
     152      foreach (bool b in maximization) {
     153        invMax[i++] = !b;
     154      }
     155      return GetBestPoint(value, invMax);
     156    }
     157
     158    private double[] GetBestPoint(DoubleMatrix value, bool[] maximization) {
     159      double[] res = new double[maximization.Length];
     160      for (int i = 0; i < maximization.Length; i++) {
     161        res[i] = maximization[i] ? Double.MinValue : Double.MaxValue;
     162      }
     163
     164      for (int r = 0; r < value.Rows; r++) {
     165        for (int c = 0; c < maximization.Length; c++) {
     166          res[c] = maximization[c] ? Math.Max(res[c], value[r, c]) : Math.Min(res[c], value[r, c]);
     167        }
     168      }
     169      return res;
    115170    }
    116171  }
Note: See TracChangeset for help on using the changeset viewer.