Free cookie consent management tool by TermsFeed Policy Generator

source: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization/3.3/MultiObjective/GenerationalDistanceCalculator.cs @ 16752

Last change on this file since 16752 was 16310, checked in by bwerth, 6 years ago

#2943 worked on MOBasicProblem and MOAnalyzers

File size: 3.3 KB
Line 
1#region License Information
2
3/* HeuristicLab
4 * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
5 *
6 * This file is part of HeuristicLab.
7 *
8 * HeuristicLab is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * HeuristicLab is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22#endregion
23
24#region
25using System;
26using System.Collections.Generic;
27using System.Linq;
28using HeuristicLab.Common;
29#endregion
30
31namespace HeuristicLab.Optimization {
32  /// <summary>
33  /// The generational Distance is defined as the pth-root of the sum of all d[i]^(p) divided by the size of the qualities
34  ///  where d[i] is the minimal distance the ith point of the evaluated qualities has to any point in the optimal pareto qualities.   
35  ///  p is a dampening factor and is normally set to 1.
36  ///  http://shodhganga.inflibnet.ac.in/bitstream/10603/15070/28/28_appendix_h.pdf
37  /// </summary>
38  public static class GenerationalDistanceCalculator {
39    public static double CalculateGenerationalDistance<TP1, TP2>(IEnumerable<TP1> qualities, IEnumerable<TP2> bestKnownFront, double p) where TP1 : IReadOnlyList<double> where TP2 : IReadOnlyList<double> {
40      if (qualities == null || bestKnownFront == null) throw new ArgumentNullException(nameof(qualities));
41      if (p.IsAlmost(0.0)) throw new ArgumentException("p must not be zero.");
42      var mat = bestKnownFront.ToMatrix();
43      if (mat.GetLength(0) == 0) throw new ArgumentException("Fronts must not be empty.");
44
45      alglib.kdtreebuild(mat, mat.GetLength(0), mat.GetLength(1), 0, 2, out var tree);
46      var sum = 0.0;
47      var summand = new double[1];
48      var count = 0;
49      foreach(var point in qualities) {
50        alglib.kdtreequeryknn(tree, point.ToArray(), 1, true);
51        alglib.kdtreequeryresultsdistances(tree, ref summand);
52        sum += Math.Pow(summand[0], p);
53        count++;
54      }
55
56      if (count == 0) throw new ArgumentException("Fronts must not be empty.");
57      return Math.Pow(sum, 1 / p) / count;
58    }
59
60    public static double CalculateInverseGenerationalDistance<TP1, TP2>(IEnumerable<TP1> qualities, IEnumerable<TP2> bestKnownFront, double p) where TP1 : IReadOnlyList<double> where TP2 : IReadOnlyList<double> {
61      return CalculateGenerationalDistance(bestKnownFront, qualities, p);
62    }
63
64    internal static double[,] ToMatrix<TP>(this IEnumerable<TP> source) where TP : IReadOnlyList<double> {
65      var l = source.ToArray();
66      var firstDimension = l.Length;
67      var secondDimension = l[0].Count;
68      var result = new double[firstDimension, secondDimension];
69      for (var i = 0; i < firstDimension; ++i)
70        for (var j = 0; j < secondDimension; ++j)
71          result[i, j] = l[i][j];
72
73      return result;
74    }
75  }
76}
Note: See TracBrowser for help on using the repository browser.