PaGMO  1.1.5
bf_fpras.cpp
1 /*****************************************************************************
2  * Copyright (C) 2004-2015 The PaGMO development team, *
3  * Advanced Concepts Team (ACT), European Space Agency (ESA) *
4  * *
5  * https://github.com/esa/pagmo *
6  * *
7  * act@esa.int *
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  * This program is distributed in the hope that it will be useful, *
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
17  * GNU General Public License for more details. *
18  * *
19  * You should have received a copy of the GNU General Public License *
20  * along with this program; if not, write to the *
21  * Free Software Foundation, Inc., *
22  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
23  *****************************************************************************/
24 
25 
26 #include "bf_fpras.h"
27 #include <algorithm>
28 
29 namespace pagmo { namespace util { namespace hv_algorithm {
30 
32 
38 bf_fpras::bf_fpras(const double eps, const double delta) : m_eps(eps), m_delta(delta) { }
39 
41 
49 void bf_fpras::verify_before_compute(const std::vector<fitness_vector> &points, const fitness_vector &r_point) const
50 {
51  base::assert_minimisation(points, r_point);
52 }
53 
55 
65 double bf_fpras::compute(std::vector<fitness_vector> &points, const fitness_vector &r_point) const
66 {
67  unsigned int n = points.size();
68  unsigned int dim = r_point.size();
69  boost::uint_fast64_t T = static_cast<boost::uint_fast64_t>( 12. * std::log( 1. / m_delta ) / std::log( 2. ) * n / m_eps / m_eps );
70 
71  // Partial sums of consecutive boxes
72  std::vector<double> sums(n, 0.0);
73 
74  // points iterator
75  std::vector<fitness_vector>::iterator it_p;
76 
77  // volume iterator - used for finding the contributor using std::lower_bound
78  std::vector<double>::iterator it_sums;
79 
80  unsigned int i = 0;
81 
82  // Total sum of every box
83  double V = 0.0;
84  for(it_p = points.begin() ; it_p != points.end() ; ++it_p) {
85  V = (sums[i++] = V + base::volume_between(*it_p, r_point));
86  }
87 
88  unsigned long long M = 0; // Round counter
89  unsigned long long M_sum = 0; // Total number of samples over every round so far
90 
91  // Container for the random point
92  fitness_vector rnd_point(dim, 0.0);
93 
94  while(true) {
95  // Get the random volume in-between [0, V] range, in order to choose the box with probability sums[i] / V
96  double r = m_drng() * V;
97 
98  // Find the contributor using binary search
99  it_sums = std::lower_bound(sums.begin(), sums.end(), r);
100  i = std::distance(sums.begin(), it_sums);
101 
102  // Sample a point inside the 'box' (r_point, points[i])
103  for(unsigned int d_idx = 0 ; d_idx < dim ; ++d_idx) {
104  rnd_point[d_idx] = (points[i][d_idx] + m_drng() * (r_point[d_idx] - points[i][d_idx]));
105  }
106 
107  unsigned int j = 0;
108  do {
109  if ( M_sum >= T ) {
110  return (T * V) / static_cast<double>(n * M);
111  }
112  j = static_cast<unsigned int>(n * m_drng());
113  ++M_sum;
114  } while (!(base::dom_cmp(rnd_point, points[j]) == base::DOM_CMP_B_DOMINATES_A));
115  ++M;
116  }
117 }
118 
120 
123 double bf_fpras::exclusive(const unsigned int p_idx, std::vector<fitness_vector> &points, const fitness_vector &r_point) const
124 {
125  (void)p_idx;
126  (void)points;
127  (void)r_point;
128  pagmo_throw(value_error, "This method is not supported by the bf_fpras algorithm");
129 }
130 
132 
135 unsigned int bf_fpras::least_contributor(std::vector<fitness_vector> &points, const fitness_vector &r_point) const
136 {
137  (void)points;
138  (void)r_point;
139  pagmo_throw(value_error, "This method is not supported by the bf_fpras algorithm");
140 }
141 
143 
146 unsigned int bf_fpras::greatest_contributor(std::vector<fitness_vector> &points, const fitness_vector &r_point) const
147 {
148  (void)points;
149  (void)r_point;
150  pagmo_throw(value_error, "This method is not supported by the bf_fpras algorithm");
151 }
152 
154 
157 std::vector<double> bf_fpras::contributions(std::vector<fitness_vector> &points, const fitness_vector &r_point) const
158 {
159  (void)points;
160  (void)r_point;
161  pagmo_throw(value_error, "This method is not supported by the bf_fpras algorithm");
162 }
163 
166 {
167  return base_ptr(new bf_fpras(*this));
168 }
169 
171 std::string bf_fpras::get_name() const
172 {
173  return "Hypervolume algorithm based on FPRAS";
174 }
175 
176 } } }
177 
178 BOOST_CLASS_EXPORT_IMPLEMENT(pagmo::util::hv_algorithm::bf_fpras)
Root PaGMO namespace.
unsigned int greatest_contributor(std::vector< fitness_vector > &, const fitness_vector &) const
Greatest contributor method.
Definition: bf_fpras.cpp:146
std::vector< double > contributions(std::vector< fitness_vector > &, const fitness_vector &) const
Contributions method.
Definition: bf_fpras.cpp:157
double exclusive(const unsigned int, std::vector< fitness_vector > &, const fitness_vector &) const
Exclusive method.
Definition: bf_fpras.cpp:123
bf_fpras(const double eps=1e-2, const double delta=1e-2)
Constructor.
Definition: bf_fpras.cpp:38
void verify_before_compute(const std::vector< fitness_vector > &, const fitness_vector &) const
Verify before compute.
Definition: bf_fpras.cpp:49
static double volume_between(const fitness_vector &, const fitness_vector &, unsigned int=0)
Compute volume between two points.
void assert_minimisation(const std::vector< fitness_vector > &, const fitness_vector &) const
Assert that reference point dominates every other point from the set.
std::string get_name() const
Algorithm name.
Definition: bf_fpras.cpp:171
static int dom_cmp(double *, double *, unsigned int)
Dominance comparison method.
base_ptr clone() const
Clone method.
Definition: bf_fpras.cpp:165
std::vector< double > fitness_vector
Fitness vector type.
Definition: types.h:42
boost::shared_ptr< base > base_ptr
Base hypervolume algorithm class.
Bringmann-Friedrich approximation method.
Definition: bf_fpras.h:48
double compute(std::vector< fitness_vector > &, const fitness_vector &) const
Compute method.
Definition: bf_fpras.cpp:65
unsigned int least_contributor(std::vector< fitness_vector > &, const fitness_vector &) const
Least contributor method.
Definition: bf_fpras.cpp:135