PaGMO  1.1.5
hv2d.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 "hv2d.h"
27 #include "hv3d.h"
28 
29 namespace pagmo { namespace util { namespace hv_algorithm {
30 
32 hv2d::hv2d(const bool initial_sorting) : m_initial_sorting(initial_sorting) { }
33 
35 
45 double hv2d::compute(std::vector<fitness_vector> &points, const fitness_vector &r_point) const
46 {
47  if (points.size() == 0) {
48  return 0.0;
49  } else if (points.size() == 1) {
50  return base::volume_between(points[0], r_point);
51  }
52 
53  if (m_initial_sorting) {
54  sort(points.begin(), points.end(), fitness_vector_cmp(1, '<'));
55  }
56 
57  double hypervolume = 0.0;
58 
59  // width of the sweeping line
60  double w = r_point[0] - points[0][0];
61  for(unsigned int idx = 0 ; idx < points.size() - 1 ; ++idx) {
62  hypervolume += (points[idx + 1][1] - points[idx][1]) * w;
63  w = std::max(w, r_point[0] - points[idx+1][0]);
64  }
65  hypervolume += (r_point[1] - points[points.size() - 1][1]) * w;
66 
67  return hypervolume;
68 }
69 
71 
74 bool hv2d::cmp_double_2d(double* a, double* b)
75 {
76  return a[1] < b[1];
77 }
78 
80 
92 double hv2d::compute(double** points, unsigned int n_points, double* r_point) const
93 {
94  if (n_points == 0) {
95  return 0.0;
96  }
97  else if (n_points == 1) {
98  return base::volume_between(points[0], r_point, 2);
99  }
100 
101  if (m_initial_sorting) {
102  std::sort(points, points + n_points, hv2d::cmp_double_2d);
103  }
104 
105  double hypervolume = 0.0;
106 
107  // width of the sweeping line
108  double w = r_point[0] - points[0][0];
109  for(unsigned int idx = 0 ; idx < n_points - 1 ; ++idx) {
110  hypervolume += (points[idx + 1][1] - points[idx][1]) * w;
111  w = std::max(w, r_point[0] - points[idx+1][0]);
112  }
113  hypervolume += (r_point[1] - points[n_points - 1][1]) * w;
114 
115  return hypervolume;
116 }
117 
119 
126 std::vector<double> hv2d::contributions(std::vector<fitness_vector> &points, const fitness_vector &r_point) const
127 {
128  std::vector<fitness_vector> new_points(points.size(), fitness_vector(3, 0.0));
129  fitness_vector new_r(r_point);
130  new_r.push_back(1.0);
131 
132  for(unsigned int i = 0 ; i < points.size() ; ++i) {
133  new_points[i][0] = points[i][0];
134  new_points[i][1] = points[i][1];
135  new_points[i][2] = 0.0;
136  }
137  // Set sorting to off since contributions are sorted by third dimension
138  return hv3d(false).contributions(new_points, new_r);
139 }
140 
141 
143 
146 bool hv2d::point_pairs_cmp(const std::pair<fitness_vector, unsigned int> &a, const std::pair<fitness_vector, unsigned int> &b)
147 {
148  return a.first[1] > b.first[1];
149 }
150 
153 {
154  return base_ptr(new hv2d(*this));
155 }
156 
158 std::string hv2d::get_name() const
159 {
160  return "hv2d algorithm";
161 }
162 
164 
172 void hv2d::verify_before_compute(const std::vector<fitness_vector> &points, const fitness_vector &r_point) const
173 {
174  if (r_point.size() != 2) {
175  pagmo_throw(value_error, "Algorithm hv2d works only for 2-dimensional cases.");
176  }
177 
178  base::assert_minimisation(points, r_point);
179 }
180 
181 } } }
182 
183 BOOST_CLASS_EXPORT_IMPLEMENT(pagmo::util::hv_algorithm::hv2d)
Root PaGMO namespace.
std::vector< double > contributions(std::vector< fitness_vector > &, const fitness_vector &) const
Contributions method.
Definition: hv2d.cpp:126
double compute(std::vector< fitness_vector > &, const fitness_vector &) const
Computes hypervolume method.
Definition: hv2d.cpp:45
hv2d hypervolume algorithm class
Definition: hv2d.h:44
static double volume_between(const fitness_vector &, const fitness_vector &, unsigned int=0)
Compute volume between two points.
hv2d(const bool initial_sorting=true)
Constructor.
Definition: hv2d.cpp:32
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: hv2d.cpp:158
std::vector< double > fitness_vector
Fitness vector type.
Definition: types.h:42
void verify_before_compute(const std::vector< fitness_vector > &, const fitness_vector &) const
Verify input method.
Definition: hv2d.cpp:172
boost::shared_ptr< base > base_ptr
Base hypervolume algorithm class.
hv3d hypervolume algorithm class
Definition: hv3d.h:52
base_ptr clone() const
Clone method.
Definition: hv2d.cpp:152
std::vector< double > contributions(std::vector< fitness_vector > &, const fitness_vector &) const
Contributions method.
Definition: hv3d.cpp:139
Hypervolume class.
Definition: hypervolume.h:49