28 #include <boost/math/special_functions/fpclassify.hpp>
29 #include <boost/numeric/conversion/bounds.hpp>
30 #include <boost/numeric/conversion/cast.hpp>
31 #include <boost/random/uniform_real.hpp>
32 #include <boost/ref.hpp>
44 #include "../exceptions.h"
45 #include "../population.h"
65 base::base(
int n,
int ni,
int nf,
int nc,
int nic,
const double &c_tol):
69 m_decision_vector_cache_f(
boost::numeric_cast<decision_vector_cache_type::
size_type>(cache_capacity)),
70 m_fitness_vector_cache(
boost::numeric_cast<fitness_vector_cache_type::
size_type>(cache_capacity)),
71 m_decision_vector_cache_c(
boost::numeric_cast<decision_vector_cache_type::
size_type>(cache_capacity)),
72 m_constraint_vector_cache(
boost::numeric_cast<constraint_vector_cache_type::
size_type>(cache_capacity)),
80 pagmo_throw(value_error,
"constraints tolerance must be non-negative");
82 if (n <= 0 || !nf || ni > n || nic > nc) {
83 pagmo_throw(value_error,
"invalid dimension(s)");
88 std::fill(m_lb.begin(),m_lb.end(),0);
89 std::fill(m_ub.begin(),m_ub.end(),1);
91 m_tmp_f1.resize(m_f_dimension);
92 m_tmp_f2.resize(m_f_dimension);
93 m_tmp_c1.resize(m_c_dimension);
94 m_tmp_c2.resize(m_c_dimension);
111 base::base(
int n,
int ni,
int nf,
int nc,
int nic,
const std::vector<double> &c_tol):
115 m_decision_vector_cache_f(
boost::numeric_cast<decision_vector_cache_type::
size_type>(cache_capacity)),
116 m_fitness_vector_cache(
boost::numeric_cast<fitness_vector_cache_type::
size_type>(cache_capacity)),
117 m_decision_vector_cache_c(
boost::numeric_cast<decision_vector_cache_type::
size_type>(cache_capacity)),
118 m_constraint_vector_cache(
boost::numeric_cast<constraint_vector_cache_type::
size_type>(cache_capacity)),
125 if (c_tol.size() !=
static_cast<constraint_vector::size_type
>(nc) ) {
126 pagmo_throw(value_error,
"invalid constraints vector dimension");
128 for(
unsigned int i=0; i<(m_c_dimension - m_ic_dimension);i++) {
130 pagmo_throw(value_error,
"constraints tolerance must be non-negative for equality constraints");
133 if (n <= 0 || !nf || ni > n || nic > nc) {
134 pagmo_throw(value_error,
"invalid dimension(s)");
139 std::fill(m_lb.begin(),m_lb.end(),0);
140 std::fill(m_ub.begin(),m_ub.end(),1);
142 m_tmp_f1.resize(m_f_dimension);
143 m_tmp_f2.resize(m_f_dimension);
144 m_tmp_c1.resize(m_c_dimension);
145 m_tmp_c2.resize(m_c_dimension);
164 base::base(
const double &l_value,
const double &u_value,
int n,
int ni,
int nf,
int nc,
int nic,
const double &c_tol):
168 m_decision_vector_cache_f(
boost::numeric_cast<decision_vector_cache_type::
size_type>(cache_capacity)),
169 m_fitness_vector_cache(
boost::numeric_cast<fitness_vector_cache_type::
size_type>(cache_capacity)),
170 m_decision_vector_cache_c(
boost::numeric_cast<decision_vector_cache_type::
size_type>(cache_capacity)),
171 m_constraint_vector_cache(
boost::numeric_cast<constraint_vector_cache_type::
size_type>(cache_capacity)),
179 pagmo_throw(value_error,
"constraints tolerance must be non-negative");
181 if (n <= 0 || !nf || ni > n || nic > nc) {
182 pagmo_throw(value_error,
"invalid dimension(s)");
184 if (l_value > u_value) {
185 pagmo_throw(value_error,
"value for lower bounds cannot be greater than value for upper bounds");
190 std::fill(m_lb.begin(),m_lb.end(),l_value);
191 std::fill(m_ub.begin(),m_ub.end(),u_value);
193 m_tmp_f1.resize(m_f_dimension);
194 m_tmp_f2.resize(m_f_dimension);
195 m_tmp_c1.resize(m_c_dimension);
196 m_tmp_c2.resize(m_c_dimension);
219 m_decision_vector_cache_f(
boost::numeric_cast<decision_vector_cache_type::
size_type>(cache_capacity)),
220 m_fitness_vector_cache(
boost::numeric_cast<fitness_vector_cache_type::
size_type>(cache_capacity)),
221 m_decision_vector_cache_c(
boost::numeric_cast<decision_vector_cache_type::
size_type>(cache_capacity)),
222 m_constraint_vector_cache(
boost::numeric_cast<constraint_vector_cache_type::
size_type>(cache_capacity)),
230 pagmo_throw(value_error,
"constraints tolerance must be non-negative");
232 if (!nf || m_i_dimension > lb.size() || nic > nc) {
233 pagmo_throw(value_error,
"invalid dimension(s)");
235 construct_from_iterators(lb.begin(),lb.end(),ub.begin(),ub.end());
237 m_tmp_f1.resize(m_f_dimension);
238 m_tmp_f2.resize(m_f_dimension);
239 m_tmp_c1.resize(m_c_dimension);
240 m_tmp_c2.resize(m_c_dimension);
259 return typeid(*this).name();
290 if (lb.size() != ub.size() || lb.size() != m_lb.size()) {
291 pagmo_throw(value_error,
"invalid or inconsistent bounds dimensions in set_bounds()");
293 verify_bounds(lb.begin(),lb.end(),ub.begin(),ub.end());
309 if (l_value > u_value) {
310 pagmo_throw(value_error,
"lower bound cannot be greater than upper bound in set_bounds()");
312 std::fill(m_lb.begin(),m_lb.end(),l_value);
313 std::fill(m_ub.begin(),m_ub.end(),u_value);
327 if (l_value > u_value) {
328 pagmo_throw(value_error,
"lower bound cannot be greater than upper bound in set_bounds()");
344 if (lb.size() != m_lb.size()) {
345 pagmo_throw(value_error,
"invalid bounds dimension in set_lb()");
347 verify_bounds(lb.begin(),lb.end(),m_ub.begin(),m_ub.end());
363 if (i >= m_lb.size() || m_ub[i] < value) {
364 pagmo_throw(value_error,
"invalid index and/or value for lower bound");
379 for (
size_type i = 0; i < m_lb.size(); ++i) {
380 if (m_ub[i] < value) {
381 pagmo_throw(value_error,
"invalid value for lower bound");
384 std::fill(m_lb.begin(),m_lb.end(),value);
397 if (ub.size() != m_lb.size()) {
398 pagmo_throw(value_error,
"invalid bounds dimension in set_ub()");
400 verify_bounds(m_lb.begin(),m_lb.end(),ub.begin(),ub.end());
416 if (i >= m_lb.size() || m_lb[i] > value) {
417 pagmo_throw(value_error,
"invalid index and/or value for upper bound");
432 for (
size_type i = 0; i < m_lb.size(); ++i) {
433 if (m_lb[i] > value) {
434 pagmo_throw(value_error,
"invalid value for upper bound");
437 std::fill(m_ub.begin(),m_ub.end(),value);
476 return m_i_dimension;
485 return m_f_dimension;
494 return m_c_dimension;
503 return m_ic_dimension;
525 retval += (m_ub[i] - m_lb[i]) * (m_ub[i] - m_lb[i]);
527 return std::sqrt(retval);
547 pagmo_throw(value_error,
"invalid chromosome length");
567 if (f.size() != m_f_dimension) {
568 pagmo_throw(value_error,
"wrong fitness vector size when calling objective function");
571 pagmo_throw(value_error,
"wrong decision vector size when calling objective function");
574 typedef decision_vector_cache_type::iterator x_iterator;
575 typedef fitness_vector_cache_type::iterator f_iterator;
576 const x_iterator x_it = std::find(m_decision_vector_cache_f.begin(),m_decision_vector_cache_f.end(),x);
577 if (x_it == m_decision_vector_cache_f.end()) {
583 if (f.size() != m_f_dimension) {
584 pagmo_throw(value_error,
"fitness dimension was changed inside objfun_impl()");
587 m_decision_vector_cache_f.push_front(x);
588 m_fitness_vector_cache.push_front(f);
591 f_iterator f_it = m_fitness_vector_cache.begin();
592 std::advance(f_it,std::distance(m_decision_vector_cache_f.begin(),x_it));
593 pagmo_assert(f_it != m_fitness_vector_cache.end());
598 x_iterator tmp_x_it = m_decision_vector_cache_f.begin();
599 f_iterator tmp_f_it = m_fitness_vector_cache.begin();
600 while (x_it != tmp_x_it) {
601 x_it->swap(*tmp_x_it);
602 f_it->swap(*tmp_f_it);
606 pagmo_assert(tmp_f_it == f_it);
621 if (v_f1.size() != m_f_dimension || v_f2.size() != m_f_dimension) {
622 pagmo_throw(value_error,
"invalid sizes for fitness vector(s) during comparison");
641 pagmo_assert(v_f1.size() == v_f2.size());
644 if (v_f1[i] < v_f2[i]) {
647 if (v_f1[i] == v_f2[i]) {
651 return ( ( (count1+count2) == v_f1.size()) && (count1>0) );
667 std::ostringstream s;
668 s <<
"Problem name: " <<
get_name() <<
'\n';
670 s <<
"\tGlobal dimension:\t\t\t" << size <<
'\n';
671 s <<
"\tInteger dimension:\t\t\t" << m_i_dimension <<
'\n';
672 s <<
"\tFitness dimension:\t\t\t" << m_f_dimension <<
'\n';
673 s <<
"\tConstraints dimension:\t\t\t" << m_c_dimension <<
'\n';
674 s <<
"\tInequality constraints dimension:\t" << m_ic_dimension <<
'\n';
675 s <<
"\tLower bounds: ";
677 s <<
"\tUpper bounds: ";
679 s <<
"\tConstraints tolerance: ";
680 s << m_c_tol <<
'\n';
693 return std::string();
740 m_c_dimension != p.m_c_dimension || m_ic_dimension != p.m_ic_dimension)
762 pagmo_assert(m_tmp_f1.size() == m_f_dimension && m_tmp_f2.size() == m_f_dimension);
767 pagmo_assert(m_tmp_c1.size() == m_c_dimension && m_tmp_c2.size() == m_c_dimension);
772 return compare_fc(m_tmp_f1,m_tmp_c1,m_tmp_f2,m_tmp_c2);
789 if (f1.size() != m_f_dimension || f2.size() != m_f_dimension) {
790 pagmo_throw(value_error,
"wrong size(s) for fitness vector(s)");
792 if (c1.size() != m_c_dimension || c2.size() != m_c_dimension) {
793 pagmo_throw(value_error,
"wrong size(s) for constraint vector(s)");
824 if (test1 && !test2) {
827 if (!test1 && test2) {
836 pagmo_assert(!test2);
862 std::fill(c.begin(),c.end(),0);
877 pagmo_throw(value_error,
"invalid constraint and/or decision vector(s) size(s) during constraint testing");
880 if (!m_c_dimension) {
884 typedef decision_vector_cache_type::iterator x_iterator;
885 typedef constraint_vector_cache_type::iterator c_iterator;
886 const x_iterator x_it = std::find(m_decision_vector_cache_c.begin(),m_decision_vector_cache_c.end(),x);
887 if (x_it == m_decision_vector_cache_c.end()) {
893 pagmo_throw(value_error,
"constraints dimension was changed inside compute_constraints_impl()");
896 m_decision_vector_cache_c.push_front(x);
897 m_constraint_vector_cache.push_front(c);
900 c_iterator c_it = m_constraint_vector_cache.begin();
901 std::advance(c_it,std::distance(m_decision_vector_cache_c.begin(),x_it));
902 pagmo_assert(c_it != m_constraint_vector_cache.end());
907 x_iterator tmp_x_it = m_decision_vector_cache_c.begin();
908 c_iterator tmp_c_it = m_constraint_vector_cache.begin();
909 while (x_it != tmp_x_it) {
910 x_it->swap(*tmp_x_it);
911 c_it->swap(*tmp_c_it);
915 pagmo_assert(tmp_c_it == c_it);
965 pagmo_assert(i < m_c_dimension);
966 if (i < m_c_dimension - m_ic_dimension) {
968 return (std::abs(c[i]) <= m_c_tol[i]);
970 return c[i] <= m_c_tol[i];
984 if (c.size() != m_c_dimension) {
985 pagmo_throw(value_error,
"invalid size for constraint vector");
987 pagmo_assert(m_c_dimension >= m_ic_dimension);
1007 if (c1.size() != m_c_dimension || c2.size() != m_c_dimension) {
1008 pagmo_throw(value_error,
"invalid size(s) for constraint vector(s)");
1029 pagmo_assert(c1.size() == c2.size() && c1.size() == m_c_dimension);
1033 double norm1 = 0, norm2 = 0;
1035 for (
c_size_type i = 0; i < m_c_dimension - m_ic_dimension; ++i) {
1042 norm1 += std::abs(c1[i]) * std::abs(c1[i]);
1043 norm2 += std::abs(c2[i]) * std::abs(c2[i]);
1046 for (
c_size_type i = m_c_dimension - m_ic_dimension; i < m_c_dimension; ++i) {
1050 norm1 += c1[i] * c1[i];
1055 norm2 += c2[i] * c2[i];
1058 if (count1 > count2) {
1060 }
else if (count1 < count2) {
1063 return (norm1 < norm2);
1093 return !(*
this == p);
1115 if (x[i] < m_lb[i] || x[i] > m_ub[i]) {
1119 if (i >= (
get_dimension() - m_i_dimension) && double_to_int::convert(x[i]) != x[i]) {
1128 void base::normalise_bounds()
1130 pagmo_assert(m_lb.size() >= m_i_dimension);
1132 bool bounds_fixed =
false;
1133 for (
size_type i = 0; i < m_lb.size() - m_i_dimension; ++i) {
1135 if (boost::math::isnan(m_lb[i]) || boost::math::isnan(m_ub[i])) {
1138 bounds_fixed =
true;
1141 if (boost::math::isinf(m_lb[i])) {
1142 m_lb[i] = (m_lb[i] > 0) ? boost::numeric::bounds<double>::highest() : boost::numeric::bounds<double>::lowest();
1143 bounds_fixed =
true;
1145 if (boost::math::isinf(m_ub[i])) {
1146 m_ub[i] = (m_ub[i] > 0) ? boost::numeric::bounds<double>::highest() : boost::numeric::bounds<double>::lowest();
1147 bounds_fixed =
true;
1150 for (
size_type i = m_lb.size() - m_i_dimension; i < m_lb.size(); ++i) {
1152 if (m_lb[i] < INT_MIN) {
1154 bounds_fixed =
true;
1156 if (m_lb[i] > INT_MAX) {
1158 bounds_fixed =
true;
1160 if (m_ub[i] < INT_MIN) {
1162 bounds_fixed =
true;
1164 if (m_ub[i] > INT_MAX) {
1166 bounds_fixed =
true;
1169 if (m_lb[i] != double_to_int::convert(m_lb[i])) {
1170 m_lb[i] = double_to_int::convert(m_lb[i]);
1171 bounds_fixed =
true;
1173 if (m_ub[i] != double_to_int::convert(m_ub[i])) {
1174 m_ub[i] = double_to_int::convert(m_ub[i]);
1175 bounds_fixed =
true;
1179 pagmo_throw(value_error,
"problem bounds were invalid and had to be fixed");
1222 pagmo_throw(not_implemented_error,
"sparsity is not implemented for this problem");
1240 pagmo_throw(value_error,
"cannot estimate pattern from this decision vector: not compatible with problem");
1242 size_type Dc = m_lb.size() - m_i_dimension;
1248 iGfun.resize(0);jGvar.resize(0); lenG=0;
1256 if (m_ub[j] == m_lb[j])
continue;
1257 x_new[j] = x0[j] + std::max(std::fabs(x0[j]), 1.0) * 1e-8;
1262 if (f_new[i]!=f0[i]) {iGfun.push_back(i); jGvar.push_back(j); lenG++;}
1266 if (c_new[i]!=c0[i]) {iGfun.push_back(i+m_f_dimension); jGvar.push_back(j); lenG++;}
1285 size_type Dc = m_lb.size() - m_i_dimension;
1289 rng_double drng(rng_generator::get<rng_double>());
1291 for (decision_vector::size_type i = 0; i<Dc;++i) {
1292 x0[i] = boost::uniform_real<double>(m_lb[i],m_ub[i])(drng);
1299 iGfun.resize(0);jGvar.resize(0); lenG=0;
1301 for (decision_vector::size_type j=0;j<Dc;++j)
1307 if (m_ub[j] == m_lb[j])
continue;
1308 x_new[j] = boost::uniform_real<double>(m_lb[j],m_ub[j])(drng);
1311 for (fitness_vector::size_type i=0;i<m_f_dimension;++i)
1313 if (f_new[i]!=f0[i]) {iGfun.push_back(i); jGvar.push_back(j); lenG++;}
1315 for (constraint_vector::size_type i=0;i<m_c_dimension;++i)
1317 if (c_new[i]!=c0[i]) {iGfun.push_back(i+m_f_dimension); jGvar.push_back(j); lenG++;}
1331 if(best_x.size() != 0){
1333 m_best_x.resize(n_opts);
1334 m_best_f.resize(n_opts);
1335 m_best_c.resize(n_opts);
1338 pagmo_throw(value_error,
"invalid size(s) for best known decision vector(s)");
1341 m_best_x.at(i) = best_x.at(i);
1343 m_best_f.at(i) =
objfun(best_x.at(i));
1415 m_decision_vector_cache_f = decision_vector_cache_type(boost::numeric_cast<decision_vector_cache_type::size_type>(
cache_capacity));
1416 m_fitness_vector_cache = fitness_vector_cache_type(boost::numeric_cast<fitness_vector_cache_type::size_type>(
cache_capacity));
1417 m_decision_vector_cache_c = decision_vector_cache_type(boost::numeric_cast<decision_vector_cache_type::size_type>(
cache_capacity));
1418 m_constraint_vector_cache = constraint_vector_cache_type(boost::numeric_cast<constraint_vector_cache_type::size_type>(
cache_capacity));
bool feasibility_x(const decision_vector &) const
Test feasibility of decision vector.
std::vector< double > decision_vector
Decision vector type.
virtual std::string human_readable_extra() const
Extra information in human readable format.
bool operator==(const base &) const
Equality operator.
void set_best_x(const std::vector< decision_vector > &)
Sets the best known decision vectors.
unsigned int get_fevals() const
Return number of function evaluations.
virtual void set_sparsity(int &lenG, std::vector< int > &iGfun, std::vector< int > &jGvar) const
Sets the sparsity pattern of the gradient.
bool feasibility_c(const constraint_vector &) const
Test feasibility of constraint vector.
fitness_vector::size_type f_size_type
Fitness' size type: the same as pagmo::fitness_vector's size type.
c_size_type get_ic_dimension() const
Return inequality constraints dimension.
unsigned int get_cevals() const
Return number of constraints function evaluations.
bool compare_constraints(const constraint_vector &, const constraint_vector &) const
Compare constraint vectors.
double get_diameter() const
Get the diameter of the problem.
std::ostream & operator<<(std::ostream &s, const base &p)
Overload stream operator for problem::base.
virtual bool compare_fitness_impl(const fitness_vector &, const fitness_vector &) const
Implementation of fitness vectors comparison.
bool compare_x(const decision_vector &, const decision_vector &) const
Compare decision vectors.
size_type get_dimension() const
Return global dimension.
void set_lb(const decision_vector &)
Set lower bounds from pagmo::decision_vector.
virtual bool equality_operator_extra(const base &) const
Extra requirements for equality.
const std::vector< constraint_vector > & get_best_c(void) const
Get the best known constraint vector.
bool operator!=(const base &) const
Inequality operator.
bool compare_fitness(const fitness_vector &, const fitness_vector &) const
Compare fitness vectors.
base(int, int=0, int=1, int=0, int=0, const double &=0)
Constructor from global dimension, integer dimension, fitness dimension, global constraints dimension...
virtual void pre_evolution(population &) const
Pre-evolution hook.
std::string human_readable() const
Return human readable representation of the problem.
fitness_vector objfun(const decision_vector &) const
Return fitness of pagmo::decision_vector.
bool test_constraint(const constraint_vector &, const c_size_type &) const
Test i-th constraint of c (using tolerance information).
bool verify_x(const decision_vector &) const
Verify compatibility of decision vector x with problem.
virtual void post_evolution(population &) const
Post-evolution hook.
const std::vector< decision_vector > & get_best_x(void) const
Get the best known decision vector.
virtual bool compare_constraints_impl(const constraint_vector &, const constraint_vector &) const
Implementation of constraint vector comparison.
size_type get_i_dimension() const
Return integer dimension.
void set_ub(const decision_vector &)
Set upper bounds from pagmo::decision_vector.
bool is_compatible(const base &) const
Compatibility operator.
const std::vector< double > & get_c_tol() const
Return constraints tolerance.
std::vector< double > fitness_vector
Fitness vector type.
constraint_vector compute_constraints(const decision_vector &) const
Compute constraints and return constraint vector.
void estimate_sparsity(const decision_vector &, int &lenG, std::vector< int > &iGfun, std::vector< int > &jGvar) const
Heuristics to estimate the sparsity pattern of the problem.
virtual bool compare_fc_impl(const fitness_vector &, const constraint_vector &, const fitness_vector &, const constraint_vector &) const
Implementation of simultaneous fitness-constraint comparison.
c_size_type get_c_dimension() const
Return global constraints dimension.
std::vector< double > constraint_vector
Constraint vector type.
const decision_vector & get_ub() const
Upper bounds getter.
virtual void objfun_impl(fitness_vector &f, const decision_vector &x) const =0
Objective function implementation.
f_size_type get_f_dimension() const
Return fitness dimension.
constraint_vector::size_type c_size_type
Constraints' size type: the same as pagmo::constraint_vector's size type.
virtual std::string get_name() const
Get problem's name.
bool compare_fc(const fitness_vector &, const constraint_vector &, const fitness_vector &, const constraint_vector &) const
Simultaneous fitness-constraint comparison.
const decision_vector & get_lb() const
Lower bounds getter.
void reset_caches() const
Reset internal caches.
void set_bounds(const decision_vector &, const decision_vector &)
Bounds setter from pagmo::decision_vector.
const std::vector< fitness_vector > & get_best_f(void) const
Get the best known fitness vector.
virtual void compute_constraints_impl(constraint_vector &, const decision_vector &) const
Implementation of constraint computation.
decision_vector::size_type size_type
Problem's size type: the same as pagmo::decision_vector's size type.
static const std::size_t cache_capacity
Capacity of the internal caches.
This rng returns a double in the [0,1[ range.
virtual ~base()
Trivial destructor.