Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
02/15/16 17:19:34 (8 years ago)
Author:
bwerth
Message:

#1087 regorganized testfunctions, added view for qualities

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/HeuristicLab.Problems.MultiObjectiveTestFunctions/HeuristicLab.Problems.MultiObjectiveTestFunctions/3.3/Comparators/HyperVolumeFast.cs

    r13562 r13620  
    11using System;
    22using System.Collections.Generic;
    3 using HeuristicLab.Encodings.RealVectorEncoding;
     3using HeuristicLab.Common;
     4using HeuristicLab.Problems.MultiObjectiveTestFunctions.Comparators;
    45
    56namespace HeuristicLab.Problems.MultiObjectiveTestFunctions {
     
    2930  public class FastHypervolume {
    3031
    31     private RealVector reference;
     32    private double[] reference;
    3233    private bool[] maximization;
    33     public FastHypervolume(RealVector reference, 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");
    3536      this.reference = reference;
    3637      this.maximization = maximization;
    3738    }
    3839
    39     public double Compare(RealVector[] front, RealVector[] optimalFront, double[][] bounds) {
     40    public double Compare(IEnumerable<double[]> front, IEnumerable<double[]> optimalFront, double[,] bounds) {
    4041      return GetHypervolume(optimalFront, bounds) - GetHypervolume(front, bounds);
    4142
     
    4950    /// <param name="bounds">also called region</param>
    5051    /// <returns></returns>
    51     public double GetHypervolume(RealVector[] front, double[][] bounds) {
     52    public double GetHypervolume(IEnumerable<double[]> front, double[,] bounds) {
    5253      //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[]>();
    5456      list.AddRange(front);
    55       list.Sort(new DimensionComparer(reference.Length - 1, maximization[reference.Length - 1]));
     57      list.Sort(Utilities.getDimensionComparer(reference.Length - 1, maximization[reference.Length - 1]));
    5658      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);
    5860      return results.Volume;
    5961
    6062    }
     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
    6187
    6288    private double[][] DeepClone(double[][] array) {
     
    6490      for (int i = 0; i < copy.Length; i++) {
    6591        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++) {
    6793          copy[i][j] = array[i][j];
    6894        }
     
    80106
    81107      public int D {
    82         get { return D; }
     108        get { return d; }
    83109      }
    84110      public ExPrivates(FastHypervolume hv) {
     
    91117    }
    92118
    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) {
    94120      double coverNew = cover;
    95       int coverIndex = 1;
     121      int coverIndex = 0;
    96122      bool allPiles = true;
    97       int bound = -1;
     123      double bound = -1;
    98124
    99125      /* is the region completely covered? */
     
    101127        if (covers(points[coverIndex], region, results)) {
    102128          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; }
    110135
    111136      if (allPiles) {
    112137        /* calculate volume by sweeping along dimension d */
    113138        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];
    116141
    117142        double next;//bernhard
    118143        do {
    119           double current = points[i][results.D];
     144          double current = points[i][results.D-1];
    120145          do {
    121             int pile = getPile(points[i], region);
     146            int pile = checkPile(points[i], region,results);
    122147            if (points[i][pile] < trellis[pile]) trellis[pile] = points[i][pile];
    123148            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;
    125150          } while (current == next);
    126           results.Volume += measure(trellis, region) * (next - current);
     151          results.Volume += measure(trellis, region, results) * (next - current);
    127152        } while (next != coverNew);
    128153
     
    131156        do {
    132157          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++) {
    134159            var intersection = intersects(points[i], region, split);
    135160            if (intersection == 1) intersect.Add(points[i][split]);
    136161            if (intersection == 0) nonIntersect.Add(points[i][split]);
    137162          }
    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();
    140165          else split++;
    141166        } while (bound == -1);
     
    145170      var regionC = DeepClone(region);
    146171      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);
    150175      }
    151176      if (pointsC.Count != 0) GetHV(regionC, pointsC, split, coverNew, results);
     
    153178      regionC = region;
    154179      regionC[split][0] = bound;
    155       pointsC = new List<RealVector>();
     180      pointsC = new List<double[]>();
    156181      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);
    158183      }
    159184      if (pointsC.Count != 0) GetHV(regionC, pointsC, split, coverNew, results);
     
    161186    }
    162187
    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) {
    164255      int pile = -1;
    165       for (int j = 1; j < results.D; j++) {
     256      for (int j = 0; j < results.D-1; j++) {
    166257        if (point[j] > region[j][0]) {
    167258          if (pile != -1) return -1;
     
    173264    }
    174265
    175     private int intersects(RealVector point, double[][] region, int split) {
     266    private int intersects(double[] point, double[][] region, int split) {
    176267      if (region[split][0] >= point[split]) return -1;
    177268      for (int j = 1; j < split; j++) {
     
    182273    }
    183274
    184     private bool covers(RealVector point, double[][] region, ExPrivates results) {
     275    private bool covers(double[] point, double[][] region, ExPrivates results) {
    185276      for (int j = 1; j < results.D; j++) {
    186277        if (point[j] > region[j][0]) return false;
     
    190281    }
    191282
    192     private bool partCovers(RealVector point, double[][] region, ExPrivates results) {
     283    private bool partCovers(double[] point, double[][] region, ExPrivates results) {
    193284      for (int j = 1; j < results.D; j++) {
    194285        if (point[j] >= region[j][1]) return false;
     
    197288    }
    198289
    199     public static double GetHypervolume(RealVector[] front, RealVector reference, bool[] maximization) {
    200       Hypervolume comp = new Hypervolume(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(RealVector point, 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) {
    209300      if (!maximization[dim] && point[dim] > reference[dim]) throw new Exception("Reference Point must be dominated by all points of the front");
    210301      if (maximization[dim] && point[dim] < reference[dim]) throw new Exception("Reference Point must be dominated by all points of the front");
    211302    }
    212303
    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
    232312
    233313  }
Note: See TracChangeset for help on using the changeset viewer.