32 #include <boost/numeric/conversion/cast.hpp>
34 namespace pagmo {
namespace util {
namespace hv_algorithm {
48 m_dimension = r_point.size();
49 m_total_size = points.size();
50 m_sqrt_size = sqrt(boost::numeric_cast<double>(m_total_size));
55 m_region_low =
new double[m_dimension - 1];
56 m_region_up =
new double[m_dimension - 1];
57 m_boundaries =
new double[m_total_size];
58 m_no_boundaries =
new double[m_total_size];
59 m_piles =
new int[m_total_size];
60 m_trellis =
new double[m_dimension - 1];
63 for (
int i = 0 ; i < m_dimension - 1 ; ++i) {
64 m_region_up[i] = r_point[i];
65 m_region_low[i] = std::numeric_limits<double>::max();
68 double** initial_points =
new double*[m_total_size];
69 for (
int n = 0 ; n < m_total_size ; ++n) {
70 initial_points[n] =
new double[m_dimension];
72 initial_points[n][m_dimension - 1] = points[n][m_dimension - 1];
73 for (
int i = 0 ; i < m_dimension - 1 ; ++i) {
74 initial_points[n][i] = points[n][i];
75 if(initial_points[n][i] < m_region_low[i]) {
76 m_region_low[i] = (double)initial_points[n][i];
82 stream(m_region_low, m_region_up, initial_points, m_total_size, 0, r_point[m_dimension - 1], 0);
85 for (
unsigned int n = 0; n < m_child_points.size() ; ++n) {
86 delete[] m_child_points[n];
88 m_child_points.clear();
91 for (
int n = 0; n < m_total_size ; ++n) {
92 delete[] initial_points[n];
94 delete[] initial_points;
97 delete[] m_region_low;
99 delete[] m_boundaries;
100 delete[] m_no_boundaries;
107 bool hoy::covers(
const double cub[],
const double reg_low[])
const
109 for (
int i = 0; i < m_dimension - 1; ++i) {
110 if (cub[i] > reg_low[i]) {
117 bool hoy::part_covers(
const double cub[],
const double reg_up[])
const
119 for (
int i = 0; i < m_dimension - 1; ++i) {
120 if (cub[i] >= reg_up[i]) {
127 int hoy::contains_boundary(
const double cub[],
const double reg_low[],
const int split)
const
130 if (reg_low[split] >= cub[split]){
136 for (
int j = 0 ; j < split; ++j) {
137 if (reg_low[j] < cub[j]) {
147 double hoy::get_measure(
const double reg_low[],
const double reg_up[])
const
150 for (
int i = 0 ; i < m_dimension - 1 ; ++i) {
151 vol *= (reg_up[i] - reg_low[i]);
156 int hoy::is_pile(
const double cub[],
const double reg_low[])
const
159 int pile = m_dimension;
161 for (
int k = 0 ; k < m_dimension - 1 ; ++k) {
163 if (cub[k] > reg_low[k]) {
164 if (pile != m_dimension) {
181 double hoy::compute_trellis(
const double reg_low[],
const double reg_up[],
const double trellis[])
const
186 for (
int i = 0 ; i < m_dimension - 1 ; ++i) {
188 total *= (reg_up[i] - reg_low[i]);
189 empty *= (trellis[i] - reg_low[i]);
191 return total - empty;
194 double hoy::get_median(
double* bounds,
unsigned int n)
const
197 return bounds[n - 1];
199 unsigned int n2 = n/2;
200 std::partial_sort(bounds, bounds + n2, bounds + n);
205 void hoy::stream(
double m_region_low[],
double m_region_up[],
double** points,
const unsigned int n_points,
int split,
double cover,
unsigned int rec_level)
const
207 double cover_old = cover;
208 unsigned int cover_index = 0;
212 double plane_area = get_measure(m_region_low, m_region_up);
213 while (cover == cover_old && cover_index < n_points) {
214 if ( covers(points[cover_index], m_region_low) ) {
216 cover = points[cover_index][m_dimension - 1];
217 m_volume += plane_area * (cover_old - cover);
230 for (
int c = cover_index ; c > 0; --c) {
231 if (points[c - 1][m_dimension - 1] == cover) {
237 if (cover_index == 0) {
243 bool all_piles =
true;
245 for (
unsigned int i = 0; i < cover_index; ++i) {
246 m_piles[i] = is_pile(points[i], m_region_low);
247 if (m_piles[i] == -1) {
262 for (
int c = 0 ; c < m_dimension - 1; ++c) {
263 m_trellis[c] = m_region_up[c];
266 double current = 0.0;
270 current = points[i][m_dimension-1];
272 if (points[i][m_piles[i]] < m_trellis[m_piles[i]]) {
273 m_trellis[m_piles[i]] = points[i][m_piles[i]];
276 if (i < cover_index) {
277 next = points[i][m_dimension - 1];
282 }
while(next == current);
283 m_volume += compute_trellis(m_region_low, m_region_up, m_trellis) * (next - current);
284 }
while(next != cover);
290 bool not_found =
true;
291 unsigned int n_bounds = 0;
292 unsigned int n_no_bounds = 0;
295 for (
unsigned int i = 0; i < cover_index; ++i) {
296 int contained = contains_boundary(points[i], m_region_low, split);
297 if (contained == 1) {
298 m_boundaries[n_bounds++] = points[i][split];
299 }
else if (contained == 0) {
300 m_no_boundaries[n_no_bounds++] = points[i][split];
306 bound = get_median(m_boundaries, n_bounds);
309 else if (n_no_bounds > m_sqrt_size) {
310 bound = get_median(m_no_boundaries, n_no_bounds);
319 if (rec_level >= m_child_points.size()) {
320 m_child_points.push_back(
new double*[m_total_size]);
323 unsigned int n_cp = 0;
325 double d_last = m_region_up[split];
327 m_region_up[split] = bound;
328 for (
unsigned int i = 0; i < cover_index ; ++i) {
329 if (part_covers(points[i], m_region_up)) {
330 m_child_points[rec_level][n_cp++] = points[i];
334 stream(m_region_low, m_region_up, m_child_points[rec_level], n_cp, split, cover, rec_level + 1);
339 m_region_up[split] = d_last;
340 d_last = m_region_low[split];
341 m_region_low[split] = bound;
342 for (
unsigned int i = 0 ; i < cover_index ; ++i) {
343 if (part_covers(points[i], m_region_up)) {
344 m_child_points[rec_level][n_cp++] = points[i];
348 stream(m_region_low, m_region_up, m_child_points[rec_level], n_cp, split, cover, rec_level + 1);
350 m_region_low[split] = d_last;
377 return "HOY algorithm";
Fitness vector comparator class.
void assert_minimisation(const std::vector< fitness_vector > &, const fitness_vector &) const
Assert that reference point dominates every other point from the set.
base_ptr clone() const
Clone method.
std::vector< double > fitness_vector
Fitness vector type.
double compute(std::vector< fitness_vector > &, const fitness_vector &) const
Compute hypervolume.
std::string get_name() const
Algorithm name.
boost::shared_ptr< base > base_ptr
Base hypervolume algorithm class.
void verify_before_compute(const std::vector< fitness_vector > &, const fitness_vector &) const
Verify before compute method.