PaGMO  1.1.5
cstrs_core.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 <boost/random/uniform_int.hpp>
26 #include <boost/random/uniform_real.hpp>
27 #include <boost/random/variate_generator.hpp>
28 #include <boost/random/normal_distribution.hpp>
29 #include <string>
30 #include <vector>
31 
32 #include "../exceptions.h"
33 #include "../population.h"
34 #include "../problem/base.h"
35 #include "../problem/con2uncon.h"
36 #include "../types.h"
37 #include "base.h"
38 #include "cstrs_core.h"
39 
40 namespace pagmo { namespace algorithm {
41 
43 
58 cstrs_core::cstrs_core(const base &original_algo, const base &repair_algo,
59  int gen,
60  int repair_frequency,
61  double repair_ratio,
62  double ftol, double xtol):
63  base(),m_original_algo(original_algo.clone()),
64  m_repair_algo(repair_algo.clone()),
65  m_gen(gen),m_repair_frequency(repair_frequency),
66  m_repair_ratio(repair_ratio),m_ftol(ftol),m_xtol(xtol)
67 {
68 // m_original_algo = original_algo.clone();
69 // m_repair_algo = repair_algo.clone();
70 
71  if(gen < 0) {
72  pagmo_throw(value_error,"number of generations must be nonnegative");
73  }
74  if(repair_frequency < 0) {
75  pagmo_throw(value_error,"repair frequency must be positive");
76  }
77  if((repair_ratio < 0) || (repair_ratio > 1)) {
78  pagmo_throw(value_error,"repair ratio must be in [0..1]");
79  }
80 }
81 
84  base(algo),m_original_algo(algo.m_original_algo->clone()),
85  m_repair_algo(algo.m_repair_algo->clone()),m_gen(algo.m_gen),
86  m_repair_frequency(algo.m_repair_frequency),
87  m_repair_ratio(algo.m_repair_ratio),
88  m_ftol(algo.m_ftol),m_xtol(algo.m_xtol)
89 {}
90 
93 {
94  return base_ptr(new cstrs_core(*this));
95 }
96 
98 
104 {
105  // store useful variables
106  const problem::base &prob = pop.problem();
107  const population::size_type pop_size = pop.size();
108  const problem::base::size_type prob_dimension = prob.get_dimension();
109 
110  // get the constraints dimension
111  problem::base::c_size_type prob_c_dimension = prob.get_c_dimension();
112 
113  //We perform some checks to determine wether the problem/population are suitable for CORE
114  if(prob_c_dimension < 1) {
115  pagmo_throw(value_error,"The problem is not constrained and CORE is not suitable to solve it");
116  }
117  if(prob.get_f_dimension() != 1) {
118  pagmo_throw(value_error,"The problem is multiobjective and CORE is not suitable to solve it");
119  }
120 
121  // Get out if there is nothing to do.
122  if(pop_size == 0) {
123  return;
124  }
125 
126  // generates the unconstrained problem
127  problem::con2uncon prob_unconstrained(prob);
128 
129  // associates the population to this problem
130  population pop_uncon(prob_unconstrained);
131 
132  // fill this unconstrained population
133  pop_uncon.clear();
134  for(population::size_type i=0; i<pop_size; i++) {
135  pop_uncon.push_back(pop.get_individual(i).cur_x);
136  }
137 
138  // vector containing the infeasibles positions
139  std::vector<population::size_type> pop_infeasibles;
140 
141  // Main CORE loop
142  for(int k=0; k<m_gen; k++) {
143 
144  if(k%m_repair_frequency == 0) {
145  pop_infeasibles.clear();
146 
147  // get the infeasible individuals
148  for(population::size_type i=0; i<pop_size; i++) {
149  if(!prob.feasibility_c(pop.get_individual(i).cur_c)) {
150  pop_infeasibles.push_back(i);
151  }
152  }
153 
154  // random shuffle of infeasibles?
155  population::size_type number_of_repair = (population::size_type)(m_repair_ratio * pop_infeasibles.size());
156 
157  // repair the infeasible individuals
158  for(population::size_type i=0; i<number_of_repair; i++) {
159  const population::size_type &current_individual_idx = pop_infeasibles.at(i);
160 
161  pop.repair(current_individual_idx, m_repair_algo);
162  }
163 
164  // the population is repaired, it can be now used in the new unconstrained population
165  // only the repaired individuals are put back in the population
166  for(population::size_type i=0; i<number_of_repair; i++) {
167  population::size_type current_individual_idx = pop_infeasibles.at(i);
168  pop_uncon.set_x(current_individual_idx, pop.get_individual(current_individual_idx).cur_x);
169  }
170  }
171 
172  m_original_algo->evolve(pop_uncon);
173 
174  // push back the population in the main problem
175  pop.clear();
176  for(population::size_type i=0; i<pop_size; i++) {
177  pop.push_back(pop_uncon.get_individual(i).cur_x);
178  }
179 
180  // Check the exit conditions (every 40 generations, just as DE)
181  if(k % 40 == 0) {
182  decision_vector tmp(prob_dimension);
183 
184  double dx = 0;
185  for(decision_vector::size_type i=0; i<prob_dimension; i++) {
186  tmp[i] = pop.get_individual(pop.get_worst_idx()).best_x[i] - pop.get_individual(pop.get_best_idx()).best_x[i];
187  dx += std::fabs(tmp[i]);
188  }
189 
190  if(dx < m_xtol ) {
191  if (m_screen_output) {
192  std::cout << "Exit condition -- xtol < " << m_xtol << std::endl;
193  }
194  break;
195  }
196 
197  double mah = std::fabs(pop.get_individual(pop.get_worst_idx()).best_f[0] - pop.get_individual(pop.get_best_idx()).best_f[0]);
198 
199  if(mah < m_ftol) {
200  if(m_screen_output) {
201  std::cout << "Exit condition -- ftol < " << m_ftol << std::endl;
202  }
203  break;
204  }
205 
206  // outputs current values
207  if(m_screen_output) {
208  std::cout << "Generation " << k << " ***" << std::endl;
209  std::cout << " Best global fitness: " << pop.champion().f << std::endl;
210  std::cout << " xtol: " << dx << ", ftol: " << mah << std::endl;
211  std::cout << " xtol: " << dx << ", ftol: " << mah << std::endl;
212  }
213  }
214  }
215 }
216 
218 std::string cstrs_core::get_name() const
219 {
220  return m_original_algo->get_name() + "[CORE]";
221 }
222 
224 
228 {
229  return m_original_algo->clone();
230 }
231 
233 
239 {
240  m_original_algo = algo.clone();
241 }
242 
244 
248 {
249  return m_repair_algo->clone();
250 }
251 
253 
259 {
260  m_repair_algo = algo.clone();
261 }
262 
264 
268 {
269  std::ostringstream s;
270  s << "algorithms: " << m_original_algo->get_name() << " ";
271  s << "\n\tConstraints handled with CORE algorithm";
272  return s.str();
273 }
274 
275 }} //namespaces
276 
277 BOOST_CLASS_EXPORT_IMPLEMENT(pagmo::algorithm::cstrs_core)
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
void evolve(population &) const
Evolve implementation.
Definition: cstrs_core.cpp:103
const individual_type & get_individual(const size_type &) const
Get constant reference to individual at position n.
Definition: population.cpp:277
Base algorithm class.
bool feasibility_c(const constraint_vector &) const
Test feasibility of constraint vector.
constraint_vector cur_c
Current constraint vector.
Definition: population.h:87
Base problem class.
Definition: problem/base.h:148
Population class.
Definition: population.h:70
CORE constraints handling meta-algorithm.
Definition: cstrs_core.h:57
size_type get_dimension() const
Return global dimension.
Constrained to unconstrained meta-problem.
Definition: con2uncon.h:48
virtual base_ptr clone() const =0
Clone method.
fitness_vector f
Fitness vector.
Definition: population.h:153
base_ptr get_repair_algorithm() const
Get a copy of the internal local repair algorithm.
Definition: cstrs_core.cpp:247
bool m_screen_output
Indicates to the derived class whether to print stuff on screen.
std::string get_name() const
Algorithm name.
Definition: cstrs_core.cpp:218
base_ptr get_algorithm() const
Get a copy of the internal local algorithm.
Definition: cstrs_core.cpp:227
cstrs_core(const base &=jde(1), const base &=jde(1), int=1, int=10, double=1., double=1e-15, double=1e-15)
Constructor.
Definition: cstrs_core.cpp:58
c_size_type get_c_dimension() const
Return global constraints dimension.
void set_algorithm(const base &)
Set algorithm.
Definition: cstrs_core.cpp:238
base_ptr clone() const
Clone method.
Definition: cstrs_core.cpp:92
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 set_repair_algorithm(const base &)
Set algorithm.
Definition: cstrs_core.cpp:258
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.
Definition: problem/base.h:164
std::string human_readable_extra() const
Extra human readable algorithm info.
Definition: cstrs_core.cpp:267
decision_vector::size_type size_type
Problem's size type: the same as pagmo::decision_vector's size type.
Definition: problem/base.h:160