29 namespace pagmo {
namespace util {
namespace hv_algorithm {
39 hv3d::hv3d(
bool initial_sorting) : m_initial_sorting(initial_sorting) { }
58 if (m_initial_sorting) {
66 const double INF = std::numeric_limits<double>::max();
72 double z3 = points[0][2];
74 A = fabs((points[0][0] - r_point[0]) * (points[0][1] - r_point[1]));
76 std::multiset<fitness_vector>::iterator p;
77 std::multiset<fitness_vector>::iterator q;
78 for(std::vector<fitness_vector>::size_type idx = 1 ; idx < points.size() ; ++idx) {
79 p = T.insert(points[idx]);
82 if ( (*q)[1] <= (*p)[1] ) {
85 V += A * fabs(z3 - (*p)[2]);
87 std::multiset<fitness_vector>::reverse_iterator rev_it(q);
90 std::multiset<fitness_vector>::reverse_iterator erase_begin (rev_it);
91 std::multiset<fitness_vector>::reverse_iterator rev_it_pred;
92 while((*rev_it)[1] >= (*p)[1] ) {
95 A -= fabs(((*rev_it)[0] - (*rev_it_pred)[0])*((*rev_it)[1] - (*q)[1]));
98 A += fabs(((*p)[0] - (*(rev_it))[0])*((*p)[1] - (*q)[1]));
99 T.erase(rev_it.base(),erase_begin.base());
102 V += A * fabs(z3 - r_point[2]);
108 bool hv3d::hycon3d_tree_cmp::operator()(
const std::pair<fitness_vector, int> &a,
const std::pair<fitness_vector, int> &b)
110 return a.first[0] > b.first[0];
117 double hv3d::box_volume(
const box3d &b)
119 return fabs((b.ux - b.lx) * (b.uy - b.ly) * (b.uz - b.lz));
123 bool hv3d::hycon3d_sort_cmp(
const std::pair<fitness_vector, unsigned int> &a,
const std::pair<fitness_vector, unsigned int> &b)
125 return a.first[2] < b.first[2];
142 std::vector<fitness_vector> p(points.begin(), points.end());
144 std::vector<std::pair<fitness_vector, unsigned int> > point_pairs;
145 point_pairs.reserve(p.size());
146 for(
unsigned int i = 0 ; i < p.size() ; ++i) {
147 point_pairs.push_back(std::make_pair(p[i], i));
149 if (m_initial_sorting) {
150 sort(point_pairs.begin(), point_pairs.end(), hycon3d_sort_cmp);
152 for(
unsigned int i = 0 ; i < p.size() ; ++i) {
153 p[i] = point_pairs[i].first;
157 typedef std::multiset<std::pair<fitness_vector, int>, hycon3d_tree_cmp > tree_t;
159 unsigned int n = p.size();
160 const double INF = std::numeric_limits<double>::max();
163 const double NaN = INF;
166 std::vector<double> c(n, 0.0);
178 T.insert(std::make_pair(p[0], 0));
179 T.insert(std::make_pair(s_x, n + 1));
180 T.insert(std::make_pair(s_y, n + 2));
183 std::vector<std::deque<box3d> > L(n + 3);
185 box3d b(r_point[0], r_point[1], NaN, p[0][0], p[0][1], p[0][2]);
188 for (
unsigned int i = 1 ; i < n + 1 ; ++i) {
189 std::pair<fitness_vector, int> pi(p[i], i);
191 tree_t::iterator it = T.lower_bound(pi);
194 if (p[i][1] >= (*it).first[1]) {
198 tree_t::reverse_iterator r_it(it);
202 while((*r_it).first[1] > p[i][1]) {
203 d.push_back((*r_it).second);
207 int r = (*it).second;
208 int t = (*r_it).second;
210 T.erase(r_it.base(), it);
213 while(!L[r].empty()) {
214 box3d& b = L[r].front();
215 if(b.ux >= p[i][0]) {
217 c[r] += box_volume(b);
219 }
else if(b.lx > p[i][0]) {
221 c[r] += box_volume(b);
232 double xleft = p[t][0];
233 std::vector<int>::reverse_iterator r_it_idx = d.rbegin();
234 std::vector<int>::reverse_iterator r_it_idx_e = d.rend();
235 for(;r_it_idx != r_it_idx_e ; ++r_it_idx) {
236 int jdom = *r_it_idx;
237 while(!L[jdom].empty()) {
238 box3d& b = L[jdom].front();
240 c[jdom] += box_volume(b);
243 L[i].push_back(box3d(xleft, p[jdom][1], NaN, p[jdom][0], p[i][1], p[i][2]));
246 L[i].push_back(box3d(xleft, p[r][1], NaN, p[i][0], p[i][1], p[i][2]));
250 while(!L[t].empty()) {
251 box3d &b = L[t].back();
254 c[t] += box_volume(b);
261 if (xleft > p[t][0]) {
262 L[t].push_back(box3d(xleft, p[i][1], NaN, p[t][0], p[t][1], p[i][2]));
264 T.insert(std::make_pair(p[i], i));
268 std::vector<double> contribs(n, 0.0);
269 for(
unsigned int i=0;i < c.size();++i) {
270 contribs[point_pairs[i].second] = c[i];
286 if (r_point.size() != 3) {
287 pagmo_throw(value_error,
"Algorithm hv3d works only for 3-dimensional cases");
302 return "hv3d algorithm";
Fitness vector comparator class.
hv3d(bool initial_sorting=true)
Constructor.
double compute(std::vector< fitness_vector > &, const fitness_vector &) const
Compute hypervolume.
std::string get_name() const
Algorithm name.
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.
void verify_before_compute(const std::vector< fitness_vector > &, const fitness_vector &) const
Verify before compute.
WFG hypervolume algorithm.
std::vector< double > fitness_vector
Fitness vector type.
boost::shared_ptr< base > base_ptr
Base hypervolume algorithm class.
hv3d hypervolume algorithm class
std::vector< double > contributions(std::vector< fitness_vector > &, const fitness_vector &) const
Contributions method.
std::vector< double > contributions(std::vector< fitness_vector > &, const fitness_vector &) const
Contributions method.