Changeset 14018
- Timestamp:
- 07/07/16 14:13:46 (8 years ago)
- Location:
- branches/HeuristicLab.Problems.MultiObjectiveTestFunctions/HeuristicLab.Problems.MultiObjectiveTestFunctions/3.3
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/HeuristicLab.Problems.MultiObjectiveTestFunctions/HeuristicLab.Problems.MultiObjectiveTestFunctions/3.3/Calculators/Crowding.cs
r13988 r14018 32 32 /// C(A) = mean(d(x,A)) where x in A and d(x,A) is not infinite 33 33 /// </summary> 34 public class Crowding {34 public static class Crowding { 35 35 36 36 public static double Calculate(IEnumerable<double[]> front, double[,] bounds) { 37 double sum = 0; 38 int c = 0; 37 39 38 double[] pointsums = new double[front.Count()]; 40 39 41 40 for (int dim = 0; dim < front.First().Length; dim++) { 41 42 42 double[] arr = front.Select(x => x[dim]).ToArray(); 43 43 Array.Sort(arr); 44 44 45 double fmax = bounds[dim % bounds.GetLength(0), 1]; 45 46 double fmin = bounds[dim % bounds.GetLength(0), 0]; 47 46 48 int pointIdx = 0; 47 49 foreach (double[] point in front) { … … 55 57 } 56 58 59 double sum = 0; 60 int c = 0; 57 61 foreach (double d in pointsums) { 58 62 if (!Double.IsInfinity(d)) { … … 61 65 } 62 66 } 67 63 68 return c == 0 ? Double.PositiveInfinity : sum / c; 64 69 } -
branches/HeuristicLab.Problems.MultiObjectiveTestFunctions/HeuristicLab.Problems.MultiObjectiveTestFunctions/3.3/Calculators/GenerationalDistance.cs
r13672 r14018 21 21 using System; 22 22 using System.Collections.Generic; 23 using System.Linq; 23 24 24 25 namespace HeuristicLab.Problems.MultiObjectiveTestFunctions { … … 28 29 /// where d[i] is the minimal distance the ith point of the evaluated front has to any point in the optimal pareto front. 29 30 /// </summary> 30 public class GenerationalDistance {31 public static class GenerationalDistance { 31 32 32 33 public static double Calculate(IEnumerable<double[]> front, IEnumerable<double[]> optimalFront, double p) { 33 //TODO build a kd-tree, sort the array, do someting intelligent here 34 if (front == null || optimalFront == null) throw new ArgumentException("Fronts must not be null"); 34 //TODO build a kd-tree, sort the array, do something intelligent here 35 if (front == null || optimalFront == null) throw new ArgumentNullException("Fronts must not be null."); 36 if (!front.Any()) throw new ArgumentException("Front must not be empty."); 37 if (p == 0.0) throw new ArgumentException("p must not be 0.0."); 38 35 39 double sum = 0; 36 40 int c = 0; 37 41 foreach (double[] r in front) { 38 sum += Utilities. minDistance(r, optimalFront, true);42 sum += Utilities.MinimumDistance(r, optimalFront); 39 43 c++; 40 44 } 41 if (c == 0) throw new ArgumentException("Fronts must not be empty"); 45 42 46 return Math.Pow(sum, 1 / p) / c; 43 47 } 44 48 45 46 47 49 } 48 50 } -
branches/HeuristicLab.Problems.MultiObjectiveTestFunctions/HeuristicLab.Problems.MultiObjectiveTestFunctions/3.3/Calculators/HyperVolume.cs
r13988 r14018 19 19 */ 20 20 #endregion 21 using HeuristicLab.Common;22 21 using System; 23 22 using System.Collections.Generic; 24 23 using System.Linq; 24 using HeuristicLab.Common; 25 25 26 26 namespace HeuristicLab.Problems.MultiObjectiveTestFunctions { 27 27 28 public class Hypervolume {28 public static class Hypervolume { 29 29 30 30 /// <summary> … … 33 33 /// 34 34 /// Example: 35 /// r is the reference Point at (1|1) 36 /// The filled Area labled HV is the 2 di ensional Hypervolume enclosed by this front.35 /// r is the reference Point at (1|1) and every Point p is part of the evaluated front 36 /// The filled Area labled HV is the 2 dimensional Hypervolume enclosed by this front. 37 37 /// 38 38 /// (0|1) (1|1) … … 52 52 /// </summary> 53 53 /// 54 public static double Calculate(IEnumerable<double[]> points, IEnumerable<double> reference, bool[] maximization) { 55 var front = NonDominatedSelect.removeNonReferenceDominatingVectors(points, reference.ToArray<double>(), maximization, false); 56 if (maximization.Length == 2) { //Hypervolume analysis only with 2 objectives for now 57 return Hypervolume.Calculate2D(front, reference, maximization); 58 } else if (Array.TrueForAll(maximization, x => !x)) { 59 return Hypervolume.CalculateMD(front, reference); 60 } else { 61 throw new NotImplementedException("Hypervolume calculation for more than two dimensions is supported only with minimization problems"); 62 } 63 } 64 65 66 private static double Calculate2D(IEnumerable<double[]> front, IEnumerable<double> reference, bool[] maximization) { 67 List<double> list = new List<double>(); 68 foreach (double d in reference) list.Add(d); 69 double[] refp = list.ToArray<double>(); 70 if (front == null) throw new ArgumentException("Fronts must not be null"); 54 public static double Calculate(IEnumerable<double[]> points, double[] referencePoint, bool[] maximization) { 55 var front = NonDominatedSelect.removeNonReferenceDominatingVectors(points, referencePoint, maximization, false); 56 if (maximization.Length == 2) 57 return Calculate2D(front, referencePoint, maximization); 58 59 if (Array.TrueForAll(maximization, x => !x)) 60 return CalculateMD(front, referencePoint); 61 else throw new NotImplementedException("Hypervolume calculation for more than two dimensions is supported only with minimization problems."); 62 } 63 64 65 private static double Calculate2D(IEnumerable<double[]> front, double[] referencePoint, bool[] maximization) { 66 if (front == null) throw new ArgumentNullException("Front must not be null."); 67 if (!front.Any()) throw new ArgumentException("Front must not be empty."); 68 69 if (referencePoint == null) throw new ArgumentNullException("ReferencePoint must not be null."); 70 if (referencePoint.Length != 2) throw new ArgumentException("ReferencePoint must have exactly two dimensions."); 71 71 72 double[][] set = front.ToArray(); //Still no Good 72 if (set.Length == 0) throw new ArgumentException("Fronts must not be empty"); 73 if (refp.Length != set[0].Length) throw new ArgumentException("Front and referencepoint need to be of the same dimensionality"); 74 Array.Sort<double[]>(set, Utilities.getDimensionComparer(0, maximization[0])); 75 double[] last = set[set.Length - 1]; 76 CheckConsistency(last, 0, refp, maximization); 77 CheckConsistency(last, 1, refp, maximization); 73 if (set.Any(s => s.Length != 2)) throw new ArgumentException("Points in front must have exactly two dimensions."); 74 75 Array.Sort<double[]>(set, new Utilities.DimensionComparer(0, maximization[0])); 78 76 79 77 double sum = 0; 80 78 for (int i = 0; i < set.Length - 1; i++) { 81 CheckConsistency(set[i], 1, refp, maximization); 82 sum += Math.Abs((set[i][0] - set[i + 1][0])) * Math.Abs((set[i][1] - refp[1])); 83 } 84 85 sum += Math.Abs(refp[0] - last[0]) * Math.Abs(refp[1] - last[1]); 79 if (NonDominatedSelect.Dominates(referencePoint, set[i], maximization, true) == NonDominatedSelect.DominationResult.Dominates) 80 throw new ArgumentException("Reference Point must be dominated by all points of the front"); 81 sum += Math.Abs((set[i][0] - set[i + 1][0])) * Math.Abs((set[i][1] - referencePoint[1])); 82 } 83 84 double[] lastPoint = set[set.Length - 1]; 85 if (NonDominatedSelect.Dominates(referencePoint, lastPoint, maximization, true) == NonDominatedSelect.DominationResult.Dominates) 86 throw new ArgumentException("Reference Point must be dominated by all points of the front"); 87 sum += Math.Abs(lastPoint[0] - referencePoint[0]) * Math.Abs(lastPoint[1] - referencePoint[1]); 88 86 89 return sum; 87 90 } 88 91 89 private static void CheckConsistency(double[] point, int dim, double[] reference, bool[] maximization) { 90 if (!maximization[dim] && point[dim] > reference[dim]) throw new ArgumentException("Reference Point must be dominated by all points of the front"); 91 if (maximization[dim] && point[dim] < reference[dim]) throw new ArgumentException("Reference Point must be dominated by all points of the front"); 92 if (point.Length != 2) throw new ArgumentException("Only 2-dimensional cases are supported yet"); 93 } 94 95 private static double CalculateMD(IEnumerable<double[]> points, IEnumerable<double> reference) { 96 double[] referencePoint = reference.ToArray<double>(); 92 93 94 private static double CalculateMD(IEnumerable<double[]> points, double[] referencePoint) { 97 95 if (referencePoint == null || referencePoint.Length < 3) throw new ArgumentException("ReferencePoint unfit for complex Hypervolume calculation"); 98 96 if (!IsDominated(referencePoint, points)) { 99 97 throw new ArgumentException("ReferencePoint unfit for complex Hypervolume calculation"); 100 98 } 99 101 100 int objectives = referencePoint.Length; 102 List<double[]> lpoints = new List<double[]>(); 103 foreach (double[] p in points) { 104 lpoints.Add(p); 105 } 106 lpoints.StableSort(Utilities.getDimensionComparer(objectives - 1, false)); 107 108 double[] regLow = new double[objectives]; 109 for (int i = 0; i < objectives; i++) { 110 regLow[i] = 1E15; 111 } 112 foreach (double[] p in lpoints) { 101 var front = points.ToList(); 102 front.StableSort(new Utilities.DimensionComparer(objectives - 1, false)); 103 104 double[] regLow = Enumerable.Repeat(1E15, objectives).ToArray(); 105 foreach (double[] p in front) { 113 106 for (int i = 0; i < regLow.Length; i++) { 114 if ( regLow[i] > p[i]) regLow[i] = p[i];115 } 116 } 117 118 return Stream(regLow, referencePoint, lpoints, 0, referencePoint[objectives - 1], (int)Math.Sqrt(points.Count()), objectives);107 if (p[i] < regLow[i]) regLow[i] = p[i]; 108 } 109 } 110 111 return Stream(regLow, referencePoint, front, 0, referencePoint[objectives - 1], (int)Math.Sqrt(front.Count), objectives); 119 112 } 120 113 … … 209 202 //this could/should be done in Parallel 210 203 211 if (pointsChildUp.Count ()> 0) result += Stream(regionLow, regionUpC, pointsChildUp, split, cover, sqrtNoPoints, objectives);212 if (pointsChildLow.Count ()> 0) result += Stream(regionLowC, regionUp, pointsChildLow, split, cover, sqrtNoPoints, objectives);204 if (pointsChildUp.Count > 0) result += Stream(regionLow, regionUpC, pointsChildUp, split, cover, sqrtNoPoints, objectives); 205 if (pointsChildLow.Count > 0) result += Stream(regionLowC, regionUp, pointsChildLow, split, cover, sqrtNoPoints, objectives); 213 206 } 214 207 return result; … … 216 209 217 210 private static double GetMedian(double[] vector, int length) { 218 if (vector.Length != length) { 219 double[] vec = new double[length]; 220 Array.Copy(vector, vec, length); 221 vector = vec; 222 } 223 return vector.Median(); 224 211 return vector.Take(length).Median(); 225 212 } 226 213 -
branches/HeuristicLab.Problems.MultiObjectiveTestFunctions/HeuristicLab.Problems.MultiObjectiveTestFunctions/3.3/Calculators/InvertedGenerationalDistance.cs
r13672 r14018 27 27 /// where d[i] is the minimal distance the ith point of the optimal pareto front has to any point in the evaluated front. 28 28 /// </summary> 29 public class InvertedGenerationalDistance { 30 29 public static class InvertedGenerationalDistance { 31 30 public static double Calculate(IEnumerable<double[]> front, IEnumerable<double[]> optimalFront, double p) { 32 31 return GenerationalDistance.Calculate(optimalFront, front, p); -
branches/HeuristicLab.Problems.MultiObjectiveTestFunctions/HeuristicLab.Problems.MultiObjectiveTestFunctions/3.3/Calculators/MultiDimensionalHypervolume.cs
r13725 r14018 69 69 lpoints.Add(p); 70 70 } 71 lpoints.StableSort( Utilities.getDimensionComparer(objectives - 1, false));71 lpoints.StableSort(new Utilities.DimensionComparer(objectives - 1, false)); 72 72 73 73 double[] regLow = new double[objectives]; -
branches/HeuristicLab.Problems.MultiObjectiveTestFunctions/HeuristicLab.Problems.MultiObjectiveTestFunctions/3.3/Calculators/Spacing.cs
r13672 r14018 21 21 using System; 22 22 using System.Collections.Generic; 23 using System.Linq; 23 24 using HeuristicLab.Common; 24 25 … … 30 31 /// to all OTHER points in the same front 31 32 /// </summary> 32 public class Spacing {33 public static class Spacing { 33 34 34 public static double Calculate(IEnumerable<double[]> front) { 35 if (front == null) throw new ArgumentException("Fronts must not be null"); 35 public static double Calculate(IEnumerable<double[]> points) { 36 if (points == null) throw new ArgumentException("Front must not be null."); 37 if (!points.Any()) throw new ArgumentException("Front must not be empty."); 38 36 39 List<double> d = new List<double>(); 37 foreach (double[] r in front) { 38 double dist = Utilities.minDistance(r, front, false); 39 d.Add(dist >= 0 ? dist : 0); 40 foreach (double[] r in points) { 41 var point = r; 42 var otherPoints = points.Where(p => p != point).DefaultIfEmpty(point); 43 double dist = Utilities.MinimumDistance(point, otherPoints); 44 d.Add(dist); 40 45 } 41 int n = d.Count;42 if (n == 0) throw new ArgumentException("Fronts must not be empty");43 return Math.Sqrt(d.Variance() * (n - 1) / n);44 46 47 return d.StandardDeviationPop(); 45 48 } 46 49 -
branches/HeuristicLab.Problems.MultiObjectiveTestFunctions/HeuristicLab.Problems.MultiObjectiveTestFunctions/3.3/Calculators/Utilities.cs
r13771 r14018 21 21 using System; 22 22 using System.Collections.Generic; 23 using System.Linq; 23 24 24 25 namespace HeuristicLab.Problems.MultiObjectiveTestFunctions { 25 internal class Utilities { 26 internal static class Utilities { 27 internal static double MinimumDistance(double[] point, IEnumerable<double[]> points) { 28 if (point == null) throw new ArgumentNullException("Point must not be null."); 29 if (points == null) throw new ArgumentNullException("Points must not be null."); 30 if (!points.Any()) throw new ArgumentException("Points must not be empty."); 26 31 27 /// <summary> 28 /// 29 /// </summary> 30 /// <param name="point"></param> 31 /// <param name="list"></param> 32 /// <param name="reflexive"></param> 33 /// <returns>return -1 if list contains only rejected points</returns> 34 internal static double minDistance(double[] point, IEnumerable<double[]> list, bool reflexive) { 35 double min = double.MaxValue; 36 bool empty = true; 37 foreach (double[] r in list) { 38 empty = false; 39 if (!reflexive && ReferenceEquals(r, point)) continue; 40 double d = 0; 41 if (r.Length != point.Length) throw new ArgumentException("dimensions of Front and Point do not match"); 32 double minDistance = double.MaxValue; 33 foreach (double[] r in points) { 34 if (r.Length != point.Length) throw new ArgumentException("Dimensions of Points and Point do not match."); 35 36 double squaredDistance = 0; 42 37 for (int i = 0; i < r.Length; i++) { 43 d+= (point[i] - r[i]) * (point[i] - r[i]);38 squaredDistance += (point[i] - r[i]) * (point[i] - r[i]); 44 39 } 45 min = Math.Min(d, min);40 minDistance = Math.Min(squaredDistance, minDistance); 46 41 } 47 if (empty) throw new ArgumentException("Fronts must not be empty"); 48 if (min == double.MaxValue) { return -1; } 49 return Math.Sqrt(min); 42 43 return Math.Sqrt(minDistance); 50 44 } 51 45 52 internal static IComparer<double[]> getDimensionComparer(int dim, bool descending) {53 return new DimensionComparer(dim, descending);54 }55 56 57 46 internal class DimensionComparer : IComparer<double[]> { 58 private int dim;59 private int descending;47 private readonly int dim; 48 private readonly int descending; 60 49 61 50 public DimensionComparer(int dimension, bool descending) { … … 64 53 } 65 54 66 #region IComparer<DoubleArray> Members67 68 55 public int Compare(double[] x, double[] y) { 69 56 if (x[dim] < y[dim]) return -descending; … … 71 58 else return 0; 72 59 } 73 74 #endregion75 60 } 76 61 } 77 78 79 80 81 82 62 } -
branches/HeuristicLab.Problems.MultiObjectiveTestFunctions/HeuristicLab.Problems.MultiObjectiveTestFunctions/3.3/NonDominatedSelect.cs
r13991 r14018 27 27 28 28 public class NonDominatedSelect { 29 p rivateenum DominationResult { Dominates, IsDominated, IsNonDominated };29 public enum DominationResult { Dominates, IsDominated, IsNonDominated }; 30 30 31 31 public static IEnumerable<double[]> selectNonDominatedVectors(IEnumerable<double[]> qualities, bool[] maximization, bool dominateOnEqualQualities) { … … 60 60 } 61 61 62 p rivatestatic DominationResult Dominates(double[] left, double[] right, bool[] maximizations, bool dominateOnEqualQualities) {62 public static DominationResult Dominates(double[] left, double[] right, bool[] maximizations, bool dominateOnEqualQualities) { 63 63 //mkommend Caution: do not use LINQ.SequenceEqual for comparing the two quality arrays (left and right) due to performance reasons 64 64 if (dominateOnEqualQualities) {
Note: See TracChangeset
for help on using the changeset viewer.