PaGMO  1.1.5
problem/base.h
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 // 30/01/10 Created by Francesco Biscani.
26 
27 #ifndef PAGMO_PROBLEM_BASE_H
28 #define PAGMO_PROBLEM_BASE_H
29 
30 // This define was added for a MSVC compilation fix and later removed as it creates a potential
31 // problem when testing pagmo in debug
32 // #define BOOST_CB_DISABLE_DEBUG
33 
34 #include <algorithm>
35 #include <boost/circular_buffer.hpp>
36 #include <boost/numeric/conversion/cast.hpp>
37 #include <boost/shared_ptr.hpp>
38 #include <cstddef>
39 #include <iostream>
40 #include <iterator>
41 #include <string>
42 
43 #include "../config.h"
44 #include "../exceptions.h"
45 #include "../serialization.h"
46 #include "../types.h"
47 //#include "base_meta.h"
48 
49 namespace pagmo
50 {
51 // Fwd declarations.
52 class population;
53 class island;
54 
56 
59 namespace problem {
60 
62 class base;
63 
65 typedef boost::shared_ptr<base> base_ptr;
66 
68 
148 class __PAGMO_VISIBLE base
149 {
150  // Meta problems need to be able to access protected virtual functions
151  friend class base_meta;
152  // Underlying containers used for caching decision and fitness vectors.
153  typedef boost::circular_buffer<decision_vector> decision_vector_cache_type;
154  typedef boost::circular_buffer<fitness_vector> fitness_vector_cache_type;
155  typedef boost::circular_buffer<constraint_vector> constraint_vector_cache_type;
156  public:
158  static const std::size_t cache_capacity = 5;
160  typedef decision_vector::size_type size_type;
162  typedef fitness_vector::size_type f_size_type;
164  typedef constraint_vector::size_type c_size_type;
165  base(int, int = 0, int = 1, int = 0, int = 0, const double & = 0);
166  base(int, int, int, int, int, const std::vector<double> &);
167  base(const double &, const double &, int, int = 0, int = 1, int = 0, int = 0, const double & = 0);
168  base(const decision_vector &, const decision_vector &, int = 0, int = 1, int = 0, int = 0, const double & = 0);
170 
185  template <std::size_t N>
186  base(const double (&v1)[N], const double (&v2)[N], int ni = 0, int nf = 1, int nc = 0, int nic = 0, const double &c_tol = 0):
187  m_i_dimension(boost::numeric_cast<size_type>(ni)),m_f_dimension(boost::numeric_cast<f_size_type>(nf)),
188  m_c_dimension(boost::numeric_cast<c_size_type>(nc)),m_ic_dimension(boost::numeric_cast<c_size_type>(nic)),
189  m_c_tol(nc,c_tol),
190  m_decision_vector_cache_f(boost::numeric_cast<decision_vector_cache_type::size_type>(cache_capacity)),
191  m_fitness_vector_cache(boost::numeric_cast<fitness_vector_cache_type::size_type>(cache_capacity)),
192  m_decision_vector_cache_c(boost::numeric_cast<decision_vector_cache_type::size_type>(cache_capacity)),
193  m_constraint_vector_cache(boost::numeric_cast<constraint_vector_cache_type::size_type>(cache_capacity))
194  {
195  if (c_tol < 0) {
196  pagmo_throw(value_error,"constraints tolerance must be non-negative");
197  }
198  if (!m_f_dimension) {
199  pagmo_throw(value_error,"fitness dimension must be strictly positive");
200  }
201  if (m_ic_dimension > m_c_dimension) {
202  pagmo_throw(value_error,"inequality constraints dimension must not be greater than global constraints dimension");
203  }
204  construct_from_iterators(v1,v1 + N,v2,v2 + N);
205  if (m_i_dimension > m_lb.size()) {
206  pagmo_throw(value_error,"integer dimension must not be greater than global dimension");
207  }
208  // Resize properly temporary fitness and constraint storage.
209  m_tmp_f1.resize(m_f_dimension);
210  m_tmp_f2.resize(m_f_dimension);
211  m_tmp_c1.resize(m_c_dimension);
212  m_tmp_c2.resize(m_c_dimension);
213  // Normalise bounds.
214  normalise_bounds();
215  }
217 
234  template <class Iterator1, class Iterator2>
235  base(Iterator1 start1, Iterator1 end1, Iterator2 start2, Iterator2 end2, int ni = 0, int nf = 1, int nc = 0, int nic = 0, const double &c_tol = 0):
236  m_i_dimension(boost::numeric_cast<size_type>(ni)),m_f_dimension(boost::numeric_cast<f_size_type>(nf)),
237  m_c_dimension(boost::numeric_cast<c_size_type>(nc)),m_ic_dimension(boost::numeric_cast<c_size_type>(nic)),
238  m_c_tol(nc,c_tol),
239  m_decision_vector_cache_f(boost::numeric_cast<decision_vector_cache_type::size_type>(cache_capacity)),
240  m_fitness_vector_cache(boost::numeric_cast<fitness_vector_cache_type::size_type>(cache_capacity)),
241  m_decision_vector_cache_c(boost::numeric_cast<decision_vector_cache_type::size_type>(cache_capacity)),
242  m_constraint_vector_cache(boost::numeric_cast<constraint_vector_cache_type::size_type>(cache_capacity))
243  {
244  if (c_tol < 0) {
245  pagmo_throw(value_error,"constraints tolerance must be non-negative");
246  }
247  if (!m_f_dimension) {
248  pagmo_throw(value_error,"fitness dimension must be strictly positive");
249  }
250  if (m_ic_dimension > m_c_dimension) {
251  pagmo_throw(value_error,"inequality constraints dimension must not be greater than global constraints dimension");
252  }
253  construct_from_iterators(start1,end1,start2,end2);
254  if (m_i_dimension > m_lb.size()) {
255  pagmo_throw(value_error,"integer dimension must not be greater than global dimension");
256  }
257  // Properly resize temporary fitness and constraint storage.
258  m_tmp_f1.resize(m_f_dimension);
259  m_tmp_f2.resize(m_f_dimension);
260  m_tmp_c1.resize(m_c_dimension);
261  m_tmp_c2.resize(m_c_dimension);
262  // Normalise bounds.
263  normalise_bounds();
264  }
265  virtual ~base();
270  const decision_vector &get_lb() const;
271  const decision_vector &get_ub() const;
272  void set_bounds(const decision_vector &, const decision_vector &);
274 
283  template <class Iterator1, class Iterator2>
284  void set_bounds(Iterator1 start1, Iterator1 end1, Iterator2 start2, Iterator2 end2)
285  {
286  typedef typename std::iterator_traits<Iterator1>::difference_type d_type1;
287  typedef typename std::iterator_traits<Iterator2>::difference_type d_type2;
288  const d_type1 d1 = std::distance(start1,end1);
289  const d_type2 d2 = std::distance(start2,end2);
290  if (d1 != d2 || d1 != std::distance(m_lb.begin(),m_lb.end())) {
291  pagmo_throw(value_error,"invalid or inconsistent bounds dimensions in set_bounds()");
292  }
293  verify_bounds(start1,end1,start2,end2);
294  std::copy(start1,end1,m_lb.begin());
295  std::copy(start2,end2,m_ub.begin());
296  // Normalise bounds.
297  normalise_bounds();
298  }
300 
307  template <std::size_t N>
308  void set_bounds(const double (&v1)[N], const double (&v2)[N])
309  {
310  if (m_lb.size() != N) {
311  pagmo_throw(value_error,"invalid bounds dimensions in set_bounds()");
312  }
313  verify_bounds(v1,v1 + N,v2,v2 + N);
314  std::copy(v1,v1 + N,m_lb.begin());
315  std::copy(v2,v2 + N,m_ub.begin());
316  // Normalise bounds.
317  normalise_bounds();
318  }
319  void set_bounds(const double &, const double &);
320  void set_bounds(int, const double &, const double &);
321  void set_lb(const decision_vector &);
322  void set_lb(int, const double &);
323  void set_lb(const double &);
325 
332  template <class Iterator>
333  void set_lb(Iterator start, Iterator end)
334  {
335  if (std::distance(start,end) != std::distance(m_lb.begin(),m_lb.end())) {
336  pagmo_throw(value_error,"invalid bounds dimension in set_lb()");
337  }
338  verify_bounds(start,end,m_ub.begin(),m_ub.end());
339  std::copy(start,end,m_lb.begin());
340  // Normalise bounds.
341  normalise_bounds();
342  }
344 
350  template <std::size_t N>
351  void set_lb(const double (&v)[N])
352  {
353  if (N != m_lb.size()) {
354  pagmo_throw(value_error,"invalid bounds dimension in set_lb()");
355  }
356  verify_bounds(v,v + N,m_ub.begin(),m_ub.end());
357  std::copy(v,v + N,m_lb.begin());
358  // Normalise bounds.
359  normalise_bounds();
360  }
361  void set_ub(const decision_vector &);
362  void set_ub(int, const double &);
363  void set_ub(const double &);
365 
372  template <class Iterator>
373  void set_ub(Iterator start, Iterator end)
374  {
375  if (std::distance(start,end) != std::distance(m_lb.begin(),m_lb.end())) {
376  pagmo_throw(value_error,"invalid bounds dimension in set_ub()");
377  }
378  verify_bounds(m_lb.begin(),m_lb.end(),start,end);
379  std::copy(start,end,m_ub.begin());
380  // Normalise bounds.
381  normalise_bounds();
382  }
384 
390  template <std::size_t N>
391  void set_ub(const double (&v)[N])
392  {
393  if (N != m_lb.size()) {
394  pagmo_throw(value_error,"invalid bounds dimension in set_ub()");
395  }
396  verify_bounds(m_lb.begin(),m_lb.end(),v,v + N);
397  std::copy(v,v + N,m_ub.begin());
398  // Normalise bounds.
399  normalise_bounds();
400  }
402 
404  unsigned int get_fevals() const;
405  unsigned int get_cevals() const;
406  size_type get_dimension() const;
407  size_type get_i_dimension() const;
408  f_size_type get_f_dimension() const;
409  c_size_type get_c_dimension() const;
410  c_size_type get_ic_dimension() const;
411  const std::vector<double>& get_c_tol() const;
412  double get_diameter() const;
413  virtual std::string get_name() const;
415  constraint_vector compute_constraints(const decision_vector &) const;
416  void compute_constraints(constraint_vector &, const decision_vector &) const;
417  bool compare_constraints(const constraint_vector &, const constraint_vector &) const;
418  bool test_constraint(const constraint_vector &, const c_size_type &) const;
419  bool feasibility_x(const decision_vector &) const;
420  bool feasibility_c(const constraint_vector &) const;
422 
431  virtual base_ptr clone() const = 0;
432  std::string human_readable() const;
433  virtual std::string human_readable_extra() const;
434  bool operator==(const base &) const;
435  bool operator!=(const base &) const;
436  bool is_compatible(const base &) const;
437  bool compare_x(const decision_vector &, const decision_vector &) const;
438  bool verify_x(const decision_vector &) const;
439  bool compare_fc(const fitness_vector &, const constraint_vector &, const fitness_vector &, const constraint_vector &) const;
440  virtual void pre_evolution(population &) const;
441  virtual void post_evolution(population &) const;
442  protected:
443  virtual bool equality_operator_extra(const base &) const;
444  virtual void compute_constraints_impl(constraint_vector &, const decision_vector &) const;
445  virtual bool compare_constraints_impl(const constraint_vector &, const constraint_vector &) const;
446  virtual bool compare_fc_impl(const fitness_vector &, const constraint_vector &, const fitness_vector &, const constraint_vector &) const;
447  void estimate_sparsity(const decision_vector &, int& lenG, std::vector<int>& iGfun, std::vector<int>& jGvar) const;
448  void estimate_sparsity(int& lenG, std::vector<int>& iGfun, std::vector<int>& jGvar) const;
449  public:
450  virtual void set_sparsity(int& lenG, std::vector<int>& iGfun, std::vector<int>& jGvar) const;
455  fitness_vector objfun(const decision_vector &) const;
456  void objfun(fitness_vector &, const decision_vector &) const;
457  bool compare_fitness(const fitness_vector &, const fitness_vector &) const;
458  void reset_caches() const;
459  public:
460  const std::vector<constraint_vector>& get_best_c(void) const;
461  const std::vector<decision_vector>& get_best_x(void) const;
462  const std::vector<fitness_vector>& get_best_f(void) const;
463  void set_best_x(const std::vector<decision_vector>&);
464  protected:
465  virtual bool compare_fitness_impl(const fitness_vector &, const fitness_vector &) const;
467 
474  virtual void objfun_impl(fitness_vector &f, const decision_vector &x) const = 0;
476  private:
477  void normalise_bounds();
478  // Construct from iterators.
479  template <class Iterator1, class Iterator2>
480  void construct_from_iterators(Iterator1 start1, Iterator1 end1, Iterator2 start2, Iterator2 end2)
481  {
482  m_lb.insert(m_lb.end(),start1,end1);
483  m_ub.insert(m_ub.end(),start2,end2);
484  if (m_lb.size() != m_ub.size() || m_lb.size() == 0) {
485  pagmo_throw(value_error,"null or inconsistent dimension(s) for upper/lower bounds while constructing problem");
486  }
487  verify_bounds(m_lb.begin(),m_lb.end(),m_ub.begin(),m_ub.end());
488  }
489  // Verify upper/lower bounds. This must be called only after having made sure that the iterator distances
490  // are consistent.
491  template <class Iterator1, class Iterator2>
492  static void verify_bounds(Iterator1 start1, Iterator1 end1, Iterator2 start2, Iterator2 end2)
493  {
494  for (; start1 != end1 && start2 != end2; ++start1, ++start2) {
495  if (*start1 > *start2) {
496  pagmo_throw(value_error,"lower bound is greater than upper bound");
497  }
498  }
499  }
500  private:
501  friend class boost::serialization::access;
502  template <class Archive>
503  void serialize(Archive &ar, const unsigned int)
504  {
505  ar & const_cast<size_type &>(m_i_dimension);
506  ar & const_cast<f_size_type &>(m_f_dimension);
507  ar & const_cast<c_size_type &>(m_c_dimension);
508  ar & const_cast<c_size_type &>(m_ic_dimension);
509  ar & m_lb;
510  ar & m_ub;
511  ar & const_cast<std::vector<double> &>(m_c_tol);
512  ar & m_decision_vector_cache_f;
513  ar & m_fitness_vector_cache;
514  ar & m_decision_vector_cache_c;
515  ar & m_constraint_vector_cache;
516  ar & m_tmp_f1;
517  ar & m_tmp_f2;
518  ar & m_tmp_c1;
519  ar & m_tmp_c2;
520  ar & m_best_x;
521  ar & m_best_f;
522  ar & m_best_c;
523  ar & m_fevals;
524  ar & m_cevals;
525  }
526 
527  // Data members.
528  // Size of the integer part of the problem.
529  const size_type m_i_dimension;
530  // Size of the fitness vector.
531  const f_size_type m_f_dimension;
532  // Global constraints dimension.
533  const c_size_type m_c_dimension;
534  // Inequality constraints dimension
535  const c_size_type m_ic_dimension;
536  // Lower bounds.
537  decision_vector m_lb;
538  // Upper bounds.
539  decision_vector m_ub;
540  // Tolerance for constraints analysis.
541  const std::vector<double> m_c_tol;
542  // Decision vector cache for fitness.
543  mutable decision_vector_cache_type m_decision_vector_cache_f;
544  // Fitness vector cache.
545  mutable fitness_vector_cache_type m_fitness_vector_cache;
546  // Decision vector cache for constraints.
547  mutable decision_vector_cache_type m_decision_vector_cache_c;
548  // Constraint vector cache.
549  mutable constraint_vector_cache_type m_constraint_vector_cache;
550  // Temporary storage used during decision_vector comparisons.
551  mutable fitness_vector m_tmp_f1;
552  mutable fitness_vector m_tmp_f2;
553  // Temporary storage used during constraints satisfaction testing and constraints comparison.
554  mutable constraint_vector m_tmp_c1;
555  mutable constraint_vector m_tmp_c2;
556 
557  // Best known vectors
558  std::vector<decision_vector> m_best_x;
559  std::vector<fitness_vector> m_best_f;
560  std::vector<constraint_vector> m_best_c;
561 
562  // Number of function and constraints evaluations
563  mutable unsigned int m_fevals;
564  mutable unsigned int m_cevals;
565 };
566 
567 std::ostream __PAGMO_VISIBLE_FUNC &operator<<(std::ostream &, const base &);
568 
569 }
570 }
571 
572 BOOST_SERIALIZATION_ASSUME_ABSTRACT(pagmo::problem::base)
573 
574 #endif
Root PaGMO namespace.
boost::shared_ptr< base > base_ptr
Alias for shared pointer to base problem.
Definition: problem/base.h:62
std::vector< double > decision_vector
Decision vector type.
Definition: types.h:40
void set_lb(const double(&v)[N])
Lower bounds setter from raw array.
Definition: problem/base.h:351
fitness_vector::size_type f_size_type
Fitness' size type: the same as pagmo::fitness_vector's size type.
Definition: problem/base.h:162
Base problem class.
Definition: problem/base.h:148
Population class.
Definition: population.h:70
std::ostream & operator<<(std::ostream &s, const base &p)
Overload stream operator for problem::base.
Meta=problems base class.
Definition: base_meta.h:50
void set_bounds(Iterator1 start1, Iterator1 end1, Iterator2 start2, Iterator2 end2)
Bounds setter from iterators.
Definition: problem/base.h:284
std::vector< double > fitness_vector
Fitness vector type.
Definition: types.h:42
std::vector< double > constraint_vector
Constraint vector type.
Definition: types.h:44
void set_ub(Iterator start, Iterator end)
Upper bounds setter from iterators.
Definition: problem/base.h:373
base(Iterator1 start1, Iterator1 end1, Iterator2 start2, Iterator2 end2, int ni=0, int nf=1, int nc=0, int nic=0, const double &c_tol=0)
Constructor from iterators, integer dimension, fitness dimension, global constraints dimension...
Definition: problem/base.h:235
constraint_vector::size_type c_size_type
Constraints' size type: the same as pagmo::constraint_vector's size type.
Definition: problem/base.h:164
void set_bounds(const double(&v1)[N], const double(&v2)[N])
Bounds setter from raw arrays.
Definition: problem/base.h:308
void set_ub(const double(&v)[N])
Upper bounds setter from raw array.
Definition: problem/base.h:391
decision_vector::size_type size_type
Problem's size type: the same as pagmo::decision_vector's size type.
Definition: problem/base.h:160
base(const double(&v1)[N], const double(&v2)[N], int ni=0, int nf=1, int nc=0, int nic=0, const double &c_tol=0)
Constructor from raw arrays, integer dimension, fitness dimension, global constraints dimension...
Definition: problem/base.h:186
void set_lb(Iterator start, Iterator end)
Lower bounds setter from iterators.
Definition: problem/base.h:333