Changeset 13620 for branches/HeuristicLab.Problems.MultiObjectiveTestFunctions/HeuristicLab.Problems.MultiObjectiveTestFunctions/3.3/Comparators/Crowding.cs
- Timestamp:
- 02/15/16 17:19:34 (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/HeuristicLab.Problems.MultiObjectiveTestFunctions/HeuristicLab.Problems.MultiObjectiveTestFunctions/3.3/Comparators/Crowding.cs
r13562 r13620 1 1 using System; 2 2 using System.Collections.Generic; 3 using System.Linq; 4 using HeuristicLab.Data; 3 5 using HeuristicLab.Encodings.RealVectorEncoding; 6 using HeuristicLab.Problems.MultiObjectiveTestFunctions.Comparators; 4 7 5 8 namespace HeuristicLab.Problems.MultiObjectiveTestFunctions { 6 9 7 10 /// <summary> 8 /// Crowding distance d(x,A) is usually defined between a point x and a set of points 11 /// Crowding distance d(x,A) is usually defined between a point x and a set of points A 9 12 /// d(x,A) is then a weighted sum over all dimensions where for each dimension the next larger and the next smaller Point to x are subtracted 10 13 /// I extended the concept and defined the Crowding distance of a front A as the mean of the crowding distances of every point x in A 11 /// C(A) = mean( x,A) where x in A14 /// C(A) = mean(d(x,A)) where x in A and d(x,A) is not infinite 12 15 /// </summary> 13 16 public class Crowding : IMultiObjectiveDistance { 14 private double[][] bounds; 15 public Crowding(double[][] bounds) { 17 private double[,] bounds; 18 19 public Crowding(double[,] bounds) { 16 20 this.bounds = bounds; 21 17 22 } 18 23 19 20 public static double GetDistance(RealVector[] front, RealVector[] optimalFront, double[][] bounds) { 24 public static double GetDistance(IEnumerable<double[]> front, IEnumerable<double[]> optimalFront, double[,] bounds) { 21 25 return new Crowding(bounds).Compare(front, optimalFront); 22 26 } 23 27 24 25 public static double GetCrowding(RealVector[] front, double[][] bounds) { 28 public static double GetCrowding(IEnumerable<double[]> front, double[,] bounds) { 26 29 return new Crowding(bounds).Get(front); 27 30 } 28 31 29 30 public double Get(RealVector[] front) { 32 public double Get(IEnumerable<double[]> front) { 31 33 double sum = 0; 32 foreach(RealVector point in front) { 33 sum += CalcCrowding(point, front); 34 int c = 0; 35 foreach (double[] point in front) { 36 double d = CalcCrowding(point, front); 37 if (!Double.IsInfinity(d)) { 38 sum += d; 39 c++; 40 } 34 41 } 35 return sum / front.Length;42 return c==0?Double.PositiveInfinity:sum / c; 36 43 } 37 44 38 public double Compare( RealVector[] front, RealVector[]optimalFront) {45 public double Compare(IEnumerable<double[]> front, IEnumerable<double[]> optimalFront) { 39 46 return Get(optimalFront) - Get(front); 40 47 } 41 48 42 private double CalcCrowding( RealVector point, RealVector[]list) {49 private double CalcCrowding(double[] point, IEnumerable<double[]> list) { 43 50 double sum = 0; 44 51 for (int i = 0; i < point.Length; i++) { … … 48 55 } 49 56 50 private double CalcCrowding(RealVector point, RealVector[] list, int dim) { 51 double fmax = bounds[dim % bounds.Length][1]; 52 double fmin = bounds[dim % bounds.Length][0]; 53 54 Array.Sort<RealVector>(list, new DimensionComparer(dim, false)); 55 if (list[0][dim] == point[0] || list[list.Length - 1][dim] == point[0]) return Double.PositiveInfinity; 56 int pos = binarySearch(point[dim], list, dim); 57 return (list[pos + 1][dim] - list[pos - 1][dim] )/ (fmax - fmin); 58 } 59 60 private int binarySearch(double x, RealVector[] list, int dim) { 61 int low = 0; 62 int high = list.Length - 1; 63 while (high >= low) { 64 int middle = (low + high) / 2; 65 if (list[middle][dim] == x) return middle; 66 if (list[middle][dim] < x) low = middle + 1; 67 if (list[middle][dim] > x) high = middle - 1; 68 } 69 return -1; //This should never happen 70 } 71 72 private class DimensionComparer : IComparer<RealVector> { 73 private int dim; 74 private int descending; 75 76 public DimensionComparer(int dimension, bool descending) { 77 this.dim = dimension; 78 this.descending = descending ? -1 : 1; 79 } 80 81 #region IComparer<DoubleArray> Members 82 83 public int Compare(RealVector x, RealVector y) { 84 if (x[dim] < y[dim]) return -descending; 85 else if (x[dim] > y[dim]) return descending; 86 else return 0; 87 } 88 89 #endregion 57 private double CalcCrowding(double[] point, IEnumerable<double[]> list, int dim) { 58 double fmax = bounds[dim % bounds.GetLength(0), 1]; 59 double fmin = bounds[dim % bounds.GetLength(0), 0]; 60 double[][] arr = list.ToArray(); //TODO Shady 61 Array.Sort<double[]>(arr, Utilities.getDimensionComparer(dim, false)); 62 if (arr[0][dim] == point[0] || arr[arr.Length - 1][dim] == point[0]) return Double.PositiveInfinity; 63 int pos = Utilities.binarySearch(point[dim], arr, dim); 64 if (pos == 0 || pos == list.Count()-1) return Double.PositiveInfinity; 65 return (arr[pos + 1][dim] - arr[pos - 1][dim]) / (fmax - fmin); 90 66 } 91 67
Note: See TracChangeset
for help on using the changeset viewer.