PaGMO  1.1.5
cs.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 #include "cs.h"
26 #include <boost/random/uniform_int.hpp>
27 #include <boost/random/uniform_real.hpp>
28 
29 
30 namespace pagmo { namespace algorithm {
31 
33 
44 cs::cs(const int& max_eval, const double &stop_range, const double &start_range, const double &reduction_coeff)
45  :base(),m_stop_range(stop_range),m_start_range(start_range),m_reduction_coeff(reduction_coeff),m_max_eval(max_eval)
46 {
47  if (reduction_coeff >= 1 || reduction_coeff <=0) {
48  pagmo_throw(value_error,"the reduction coefficient must be smaller than one and positive, You Fool!!");
49  }
50  if (start_range > 1 || start_range <= 0) {
51  pagmo_throw(value_error,"the starting range must be smaller than one and positive, You Fool!!");
52  }
53  if (stop_range > 1 || stop_range <= 0 || stop_range>start_range) {
54  pagmo_throw(value_error,"the minimum range must be smaller than one, positive and smaller than the starting range, (o44portebat studuisse)!!");
55  }
56  if (max_eval < 0) {
57  pagmo_throw(value_error,"Maximum number of function evaluations needs to be positive");
58  }
59 }
60 
63 {
64  return base_ptr(new cs(*this));
65 }
66 
68 
76 void cs::evolve(population &pop) const
77 {
78  // Let's store some useful variables.
79  const problem::base &prob = pop.problem();
80  const problem::base::size_type D = prob.get_dimension(), prob_i_dimension = prob.get_i_dimension(), prob_c_dimension = prob.get_c_dimension(), prob_f_dimension = prob.get_f_dimension();
81  const decision_vector &lb = prob.get_lb(), &ub = prob.get_ub();
82  const population::size_type NP = pop.size();
83  const problem::base::size_type Dc = D - prob_i_dimension;
84 
85 
86  //We perform some checks to determine whether the problem/population are suitable for compass search
87  if ( Dc == 0 ) {
88  pagmo_throw(value_error,"There is no continuous part in the problem decision vector for compass search to optimise");
89  }
90 
91  if ( prob_c_dimension != 0 ) {
92  pagmo_throw(value_error,"The problem is not box constrained and compass search is not suitable to solve it");
93  }
94 
95  if ( prob_f_dimension != 1 ) {
96  pagmo_throw(value_error,"The problem is not single objective and compass search is not suitable to solve it");
97  }
98 
99  // Get out if there is nothing to do.
100  if (NP == 0 || m_max_eval == 0) {
101  return;
102  }
103 
104  //Starting point is the best individual
105  const int bestidx = pop.get_best_idx();
106  const decision_vector &x0 = pop.get_individual(bestidx).cur_x;
107  const fitness_vector &fit0 = pop.get_individual(bestidx).cur_f;
108 
109  decision_vector x=x0,newx;
110  fitness_vector f=fit0,newf=fit0;
111  bool flag = false;
112  int eval=0;
113 
114  double newrange=m_start_range;
115 
116  while (newrange > m_stop_range && eval <= m_max_eval) {
117  flag = false;
118  for (unsigned int i=0; i<Dc; i++) {
119  newx=x;
120 
121  //move up
122  newx[i] = x[i] + newrange * (ub[i]-lb[i]);
123  //feasibility correction
124  if (newx[i] > ub [i]) newx[i]=ub[i];
125 
126  prob.objfun(newf,newx); eval++;
127  if (prob.compare_fitness(newf,f)) {
128  f = newf;
129  x = newx;
130  flag=true;
131  break; //accept
132  }
133 
134  //move down
135  newx[i] = x[i] - newrange * (ub[i]-lb[i]);
136  //feasibility correction
137  if (newx[i] < lb [i]) newx[i]=lb[i];
138 
139  prob.objfun(newf,newx); eval++;
140  if (prob.compare_fitness(newf,f)) { //accept
141  f = newf;
142  x = newx;
143  flag=true;
144  break;
145  }
146  }
147  if (!flag) {
148  newrange *= m_reduction_coeff;
149  }
150  } //end while
151  std::transform(x.begin(), x.end(), pop.get_individual(bestidx).cur_x.begin(), newx.begin(),std::minus<double>()); // newx is now velocity
152  pop.set_x(bestidx,x); //new evaluation is possible here......
153  pop.set_v(bestidx,newx);
154 }
155 
157 std::string cs::get_name() const
158 {
159  return "Compass Search";
160 }
161 
162 
164 
167 std::string cs::human_readable_extra() const
168 {
169  std::ostringstream s;
170  s << "max_eval:" << m_max_eval << ' ';
171  s << "stop_range:" << m_stop_range << ' ';
172  s << "start_range:" << m_start_range << ' ';
173  s << "reduction_coeff:" << m_reduction_coeff;
174  return s.str();
175 }
176 
177 }} //namespaces
178 
179 BOOST_CLASS_EXPORT_IMPLEMENT(pagmo::algorithm::cs)
boost::shared_ptr< base > base_ptr
Alias for shared pointer to base algorithm.
Root PaGMO namespace.
std::vector< double > decision_vector
Decision vector type.
Definition: types.h:40
fitness_vector cur_f
Current fitness vector.
Definition: population.h:89
const individual_type & get_individual(const size_type &) const
Get constant reference to individual at position n.
Definition: population.cpp:277
Base algorithm class.
base_ptr clone() const
Clone method.
Definition: cs.cpp:62
Base problem class.
Definition: problem/base.h:148
Population class.
Definition: population.h:70
cs(const int &max_eval=1, const double &stop_range=0.01, const double &start_range=0.1, const double &reduction_coeff=0.5)
Constructor.
Definition: cs.cpp:44
size_type get_dimension() const
Return global dimension.
bool compare_fitness(const fitness_vector &, const fitness_vector &) const
Compare fitness vectors.
fitness_vector objfun(const decision_vector &) const
Return fitness of pagmo::decision_vector.
std::string get_name() const
Algorithm name.
Definition: cs.cpp:157
size_type get_i_dimension() const
Return integer dimension.
std::string human_readable_extra() const
Extra human readable algorithm info.
Definition: cs.cpp:167
std::vector< double > fitness_vector
Fitness vector type.
Definition: types.h:42
c_size_type get_c_dimension() const
Return global constraints dimension.
const decision_vector & get_ub() const
Upper bounds getter.
container_type::size_type size_type
Population size type.
Definition: population.h:192
decision_vector cur_x
Current decision vector.
Definition: population.h:83
void evolve(population &) const
Evolve implementation.
Definition: cs.cpp:76
f_size_type get_f_dimension() const
Return fitness dimension.
const decision_vector & get_lb() const
Lower bounds getter.
The Compass Search Solver (CS)
Definition: cs.h:63
decision_vector::size_type size_type
Problem's size type: the same as pagmo::decision_vector's size type.
Definition: problem/base.h:160