Changeset 13620 for branches/HeuristicLab.Problems.MultiObjectiveTestFunctions/HeuristicLab.Problems.MultiObjectiveTestFunctions/3.3/Comparators/HyperVolumeFast.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/HyperVolumeFast.cs
r13562 r13620 1 1 using System; 2 2 using System.Collections.Generic; 3 using HeuristicLab.Encodings.RealVectorEncoding; 3 using HeuristicLab.Common; 4 using HeuristicLab.Problems.MultiObjectiveTestFunctions.Comparators; 4 5 5 6 namespace HeuristicLab.Problems.MultiObjectiveTestFunctions { … … 29 30 public class FastHypervolume { 30 31 31 private RealVectorreference;32 private double[] reference; 32 33 private bool[] maximization; 33 public FastHypervolume( RealVectorreference, bool[] maximization) {34 if (reference.Length != 2) throw new Exception("Only 2-dimensional cases are supported yet");34 public FastHypervolume(double[] reference, bool[] maximization) { 35 if (reference.Length != 2) throw new NotSupportedException("Only 2-dimensional cases are supported yet"); 35 36 this.reference = reference; 36 37 this.maximization = maximization; 37 38 } 38 39 39 public double Compare( RealVector[] front, RealVector[] optimalFront, double[][] bounds) {40 public double Compare(IEnumerable<double[]> front, IEnumerable<double[]> optimalFront, double[,] bounds) { 40 41 return GetHypervolume(optimalFront, bounds) - GetHypervolume(front, bounds); 41 42 … … 49 50 /// <param name="bounds">also called region</param> 50 51 /// <returns></returns> 51 public double GetHypervolume( RealVector[] front, double[][] bounds) {52 public double GetHypervolume(IEnumerable<double[]> front, double[,] bounds) { 52 53 //TODO what to do if set contains dominated points 53 var list = new List<RealVector>(); 54 if (front == null) throw new ArgumentException("Fronts must not be null"); 55 var list = new List<double[]>(); 54 56 list.AddRange(front); 55 list.Sort( newDimensionComparer(reference.Length - 1, maximization[reference.Length - 1]));57 list.Sort(Utilities.getDimensionComparer(reference.Length - 1, maximization[reference.Length - 1])); 56 58 var results = new ExPrivates(this); 57 GetHV( DeepClone(bounds), list, 1, reference[reference.Length - 1], results);59 GetHV(SpanRegion(), list, 0, reference[reference.Length - 1], results); 58 60 return results.Volume; 59 61 60 62 } 63 64 private double[][] SpanRegion(double[,] bounds, int length) { 65 if (bounds.GetLength(1) != 2) throw new ArgumentException(); 66 double[][] copy = new double[length][]; 67 for (int i = 0; i < copy.Length; i++) { 68 copy[i] = new double[2]; 69 for (int j = 0; j < 2; j++) { 70 copy[i][j] = bounds[i%bounds.GetLength(0),j]; 71 } 72 } 73 return copy; 74 } 75 76 private double[][] SpanRegion() { 77 double[][] copy = new double[reference.Length][]; 78 for (int i = 0; i < copy.Length; i++) { 79 copy[i] = new double[2]; 80 copy[i][0] = 0; 81 copy[i][1] = reference[i]; 82 } 83 return copy; 84 85 } 86 61 87 62 88 private double[][] DeepClone(double[][] array) { … … 64 90 for (int i = 0; i < copy.Length; i++) { 65 91 copy[i] = new double[array[i].Length]; 66 for (int j = 0; i< array[i].Length; j++) {92 for (int j = 0; j < array[i].Length; j++) { 67 93 copy[i][j] = array[i][j]; 68 94 } … … 80 106 81 107 public int D { 82 get { return D; }108 get { return d; } 83 109 } 84 110 public ExPrivates(FastHypervolume hv) { … … 91 117 } 92 118 93 private void GetHV(double[][] region, List< RealVector> points, int split, double cover, ExPrivates results) {119 private void GetHV(double[][] region, List<double[]> points, int split, double cover, ExPrivates results) { 94 120 double coverNew = cover; 95 int coverIndex = 1;121 int coverIndex = 0; 96 122 bool allPiles = true; 97 intbound = -1;123 double bound = -1; 98 124 99 125 /* is the region completely covered? */ … … 101 127 if (covers(points[coverIndex], region, results)) { 102 128 coverNew = points[coverIndex][results.D]; 103 results.Volume += getMeasure(region) * (cover - coverNew); 104 } else { } 105 coverIndex++; 106 } 107 if (coverIndex == 1) return; 108 109 for (int i = 1; i < coverIndex; i++) { if (checkPile(points[i], region) == -1) allPiles = false; } 129 results.Volume += GetMeasure(region,results) * (cover - coverNew); 130 } else coverIndex++; 131 } 132 if (coverIndex == 0) return; 133 134 for (int i = 0; i < coverIndex; i++) { if (checkPile(points[i], region, results) == -1) allPiles = false; } 110 135 111 136 if (allPiles) { 112 137 /* calculate volume by sweeping along dimension d */ 113 138 var trellis = new double[reference.Length]; 114 int i = 1;115 for (int j = 1; j < results.D; j++) trellis[j] = reference[j];139 int i = 0; 140 for (int j = 0; j < results.D-1; j++) trellis[j] = reference[j]; 116 141 117 142 double next;//bernhard 118 143 do { 119 double current = points[i][results.D ];144 double current = points[i][results.D-1]; 120 145 do { 121 int pile = getPile(points[i], region);146 int pile = checkPile(points[i], region,results); 122 147 if (points[i][pile] < trellis[pile]) trellis[pile] = points[i][pile]; 123 148 i++; 124 if (i < coverIndex - 1) next = points[i][results.D ]; else next = coverNew;149 if (i < coverIndex - 1) next = points[i][results.D-1]; else next = coverNew; 125 150 } while (current == next); 126 results.Volume += measure(trellis, region ) * (next - current);151 results.Volume += measure(trellis, region, results) * (next - current); 127 152 } while (next != coverNew); 128 153 … … 131 156 do { 132 157 var intersect = new List<Double>(); var nonIntersect = new List<Double>(); 133 for (int i = 1; i < coverIndex; i++) {158 for (int i = 0; i < coverIndex; i++) { 134 159 var intersection = intersects(points[i], region, split); 135 160 if (intersection == 1) intersect.Add(points[i][split]); 136 161 if (intersection == 0) nonIntersect.Add(points[i][split]); 137 162 } 138 if (intersect.Count != 0) bound = median(intersect);139 else if (nonIntersect.Count > Math.Sqrt( n)) bound = median(nonIntersect);163 if (intersect.Count != 0) bound = intersect.Median(); 164 else if (nonIntersect.Count > Math.Sqrt(points.Count)) bound = nonIntersect.Median(); 140 165 else split++; 141 166 } while (bound == -1); … … 145 170 var regionC = DeepClone(region); 146 171 regionC[split][1] = bound; 147 var pointsC = new List< RealVector>();148 for (int i = 1; i < coverIndex; i++) {149 if (partCovers(points[i], regionC, results)) move(points [i], pointsC);172 var pointsC = new List<double[]>(); 173 for (int i = 0; i < coverIndex; i++) { 174 if (partCovers(points[i], regionC, results)) move(points,i, pointsC); 150 175 } 151 176 if (pointsC.Count != 0) GetHV(regionC, pointsC, split, coverNew, results); … … 153 178 regionC = region; 154 179 regionC[split][0] = bound; 155 pointsC = new List< RealVector>();180 pointsC = new List<double[]>(); 156 181 for (int i = 1; i < coverIndex; i++) { 157 if (partCovers(points[i], regionC, results)) move(points [i], pointsC);182 if (partCovers(points[i], regionC, results)) move(points,i, pointsC); 158 183 } 159 184 if (pointsC.Count != 0) GetHV(regionC, pointsC, split, coverNew, results); … … 161 186 } 162 187 163 private int checkPile(RealVector point, double[][] region, ExPrivates results) { 188 private void reinsert(List<double[]> pointsC, List<double[]> points) { 189 points.AddRange(pointsC); 190 pointsC.Clear(); 191 } 192 193 private double GetMeasure(double[][] region,ExPrivates result) { 194 double volume = 1.0; 195 // for ( std::size_t i = 0; i < regionLow.size(); i++ ) { 196 for (int i = 1; i < result.D; i++) { 197 volume *= (region[1][i] - region[0][i]); 198 } 199 return (volume); 200 } 201 202 private void move(List<double[]> points, int i, List<double[]> pointsC) { 203 double[] v = points[i]; 204 points.Remove(v); 205 pointsC.Add(v); 206 } 207 208 private double measure(double[] trellis, double[][] region, ExPrivates results) { 209 double volume=0; 210 bool[] indicator = new bool[results.D]; 211 for (int i = 0; i < results.D-1; i++) indicator[i] = true; 212 int numberSummands = integerValue(indicator); 213 214 for (int i = 0; i <= numberSummands; i++) { 215 indicator = binaryValue(i); 216 int oneCounter = 0; 217 double summand = 0; 218 for (int j = 1; j < results.D; j++) { 219 if (indicator[i] == true) { 220 summand += region[1][j] - trellis[j]; 221 oneCounter++; 222 } else { 223 summand += region[1][j] - region[0][j]; 224 } 225 } 226 if(oneCounter%2 == 0) { 227 volume -= summand; 228 } else { 229 volume += summand; 230 } 231 } 232 return volume; 233 } 234 235 private int integerValue(bool[] binary) { 236 int sum=0; 237 foreach (bool b in binary) { 238 sum = (sum << 1) + (b ? 1 : 0); 239 } 240 return sum; 241 } 242 243 private bool[] binaryValue(int integer) { 244 bool[] res = new bool[32]; 245 int i = 0; 246 while (integer != 0) { 247 res[i++]= (integer & 1)==1; 248 integer >>= 1; 249 } 250 return res; 251 252 } 253 254 private int checkPile(double[] point, double[][] region, ExPrivates results) { 164 255 int pile = -1; 165 for (int j = 1; j < results.D; j++) {256 for (int j = 0; j < results.D-1; j++) { 166 257 if (point[j] > region[j][0]) { 167 258 if (pile != -1) return -1; … … 173 264 } 174 265 175 private int intersects( RealVectorpoint, double[][] region, int split) {266 private int intersects(double[] point, double[][] region, int split) { 176 267 if (region[split][0] >= point[split]) return -1; 177 268 for (int j = 1; j < split; j++) { … … 182 273 } 183 274 184 private bool covers( RealVectorpoint, double[][] region, ExPrivates results) {275 private bool covers(double[] point, double[][] region, ExPrivates results) { 185 276 for (int j = 1; j < results.D; j++) { 186 277 if (point[j] > region[j][0]) return false; … … 190 281 } 191 282 192 private bool partCovers( RealVectorpoint, double[][] region, ExPrivates results) {283 private bool partCovers(double[] point, double[][] region, ExPrivates results) { 193 284 for (int j = 1; j < results.D; j++) { 194 285 if (point[j] >= region[j][1]) return false; … … 197 288 } 198 289 199 public static double GetHypervolume( RealVector[] front, RealVector reference, bool[] maximization) {200 Hypervolume comp = newHypervolume(reference, maximization);201 return comp.GetHypervolume(front );202 } 203 204 public static double GetDistance( RealVector[] front, RealVector[] optimalFront, RealVector reference, bool[] maximization) {205 return GetHypervolume(optimalFront, reference, maximization ) - GetHypervolume(front, reference, maximization);206 } 207 208 private void CheckConsistency( RealVectorpoint, int dim) {290 public static double GetHypervolume(IEnumerable<double[]> front, double[] reference, bool[] maximization, double[,] bounds) { 291 FastHypervolume comp = new FastHypervolume(reference, maximization); 292 return comp.GetHypervolume(front,bounds); 293 } 294 295 public static double GetDistance(IEnumerable<double[]> front, IEnumerable<double[]> optimalFront, double[] reference, bool[] maximization, double[,] bounds) { 296 return GetHypervolume(optimalFront, reference, maximization, bounds) - GetHypervolume(front, reference, maximization,bounds); 297 } 298 299 private void CheckConsistency(double[] point, int dim) { 209 300 if (!maximization[dim] && point[dim] > reference[dim]) throw new Exception("Reference Point must be dominated by all points of the front"); 210 301 if (maximization[dim] && point[dim] < reference[dim]) throw new Exception("Reference Point must be dominated by all points of the front"); 211 302 } 212 303 213 private class DimensionComparer : IComparer<RealVector> { 214 private int dim; 215 private int descending; 216 217 public DimensionComparer(int dimension, bool descending) { 218 this.dim = dimension; 219 this.descending = descending ? -1 : 1; 220 } 221 222 #region IComparer<DoubleArray> Members 223 224 public int Compare(RealVector x, RealVector y) { 225 if (x[dim] < y[dim]) return -descending; 226 else if (x[dim] > y[dim]) return descending; 227 else return 0; 228 } 229 230 #endregion 231 } 304 305 306 307 308 309 310 311 232 312 233 313 }
Note: See TracChangeset
for help on using the changeset viewer.