/*======================================================================== PISA (www.tik.ee.ethz.ch/pisa/) ======================================================================== Computer Engineering (TIK) ETH Zurich ======================================================================== SPAM - Set Preference Algorithm for Multiobjective Optimization authors: Johannes Bader, johannes.bader@tik.ee.ethz.ch Eckart Zitzler, eckart.zitzler@tik.ee.ethz.ch Marco Laumanns, laumanns@tik.ee.ethz.ch revision by: Stefan Bleuler, stefan.bleuler@tik.ee.ethz.ch Dimo Brockhoff, dimo.brockhoff@tik.ee.ethz.ch last change: 01.12.2008 ======================================================================== */ #include #include "hypervolume.h" #include "utils.h" #include "population.h" #include "dominance.h" #include "math.h" double hypervolume(double *refs, int dim) /* Usual hypervolume */ { int i; double volume; /* calculate hypervolume */ volume = 1.0; for (i = 0; i < dim; i ++) { volume *= refs[dim + i] - refs[i]; } return volume; } double compute_integral(double *refs, double bound, int dim ) { double volume=0; volume = hypervolume(refs, dim); return volume; } double calc_hypercube_integral(double *refs, int dim, int scaling, double bound) { double volume; /* factor, the WDF near front is larger then maximal hypervolume on entire search space when scaling == 0 */ double factor; double *scaledrefs; int i,j; int scalingnecessary; scaledrefs = chk_malloc(sizeof(double) * dim * 2); /* initialize factor: */ factor = 1.0; for (i=0; i 0); min = front[objective]; for (i = 1; i < no_points; i++) { value = front[i * dim + objective]; if (value < min) min = value; } return min; } int reduce_nondominated_set(double *front, int dim, int no_points, int objective, double threshold) /* remove all points which have a value <= 'threshold' regarding the dimension 'objective'; the points [0..no_points-1] in 'front' are considered; 'front' is resorted, such that points [0..n-1] represent the remaining points; 'n' is returned */ { int n; int i; n = no_points; for (i = 0; i < n; i++) if (front[i * dim + objective] <= threshold) { n--; swap(front, dim, i, n); } return n; } double calc_hypervolume_cubewise(double *front, double *refs, int no_points, int no_objectives, int dim, double bound, int scaling) { int n; double volume, distance; volume = 0; distance = 0; n = no_points; refs[no_objectives - 1] = 0.0; while (n > 0) { int no_nondominated_points; double temp_vol, temp_dist; if (no_objectives > 1) no_nondominated_points = filter_nondominated_set(front, dim, n, no_objectives - 1); else no_nondominated_points = filter_nondominated_set(front, dim, n, no_objectives); assert(no_nondominated_points <= n); assert(no_nondominated_points > 0); temp_dist = surface_unchanged_to(front, dim, n, no_objectives - 1); refs[dim + no_objectives - 1] = temp_dist; temp_vol = 0; if (no_objectives < 3) { assert(no_nondominated_points > 0); refs[0] = 0.0; refs[dim] = front[0]; temp_vol = calc_hypercube_integral(refs, dim, scaling, bound); } else temp_vol = calc_hypervolume_cubewise(front, refs, no_nondominated_points, no_objectives - 1, dim, bound, scaling); volume += temp_vol; refs[no_objectives - 1] = temp_dist; distance = temp_dist; n = reduce_nondominated_set(front, dim, n, no_objectives - 1, distance); } return volume; } double calc_hypervolume(double *front, int dim, int no_points, int no_objectives) { int n; double volume, distance; assert(no_objectives > 0); volume = 0; distance = 0; n = no_points; if (no_objectives == 1) { filter_nondominated_set(front, dim, n, 1); volume = front[0]; } else { while (n > 0) { int no_nondominated_points; double temp_vol, temp_dist; no_nondominated_points = filter_nondominated_set(front, dim, n, no_objectives - 1); temp_vol = 0; if (no_objectives < 3) { assert(no_nondominated_points > 0); temp_vol = front[0]; } else temp_vol = calc_hypervolume(front, dim, no_nondominated_points, no_objectives - 1); temp_dist = surface_unchanged_to(front, dim, n, no_objectives - 1); volume += temp_vol * (temp_dist - distance); distance = temp_dist; n = reduce_nondominated_set(front, dim, n, no_objectives - 1, distance); } } return volume; } double unaryHypervolumeIndicator(int *A, int sizea, double bound, int scaling ) { int dim = getNrOfObjectives(); double pointArray[ sizea*dim ]; double refPoints[ dim*2 ]; int i, k; for (i = 0; i < sizea; i++) for (k = 0; k < dim; k++) pointArray[i * dim + k] = getReversedObjectiveValue( A[i], k, scaling, bound ); return calc_hypervolume_cubewise(pointArray, refPoints, sizea, dim, dim, bound, scaling); }