PaGMO  1.1.5
race_algo.cpp
1 #include "race_algo.h"
2 #include "race_pop.h"
3 #include "../problem/base_stochastic.h"
4 
5 #include <algorithm>
6 
7 namespace pagmo { namespace util { namespace racing {
8 
9 namespace metrics_algos {
10 
12 static problem::base::c_size_type get_max_c_dimension(const std::vector<problem::base_ptr> &probs)
13 {
14  problem::base::c_size_type max_c_dim = 0;
15  for(std::vector<problem::base_ptr>::size_type i = 0; i < probs.size(); i++){
16  max_c_dim = std::max(max_c_dim, probs[i]->get_c_dimension());
17  }
18  return max_c_dim;
19 }
20 
22 static problem::base::c_size_type get_max_ic_dimension(const std::vector<problem::base_ptr> &probs)
23 {
24  problem::base::c_size_type max_ic_dim = 0;
25  for(std::vector<problem::base_ptr>::size_type i = 0; i < probs.size(); i++){
26  max_ic_dim = std::max(max_ic_dim, probs[i]->get_ic_dimension());
27  }
28  return max_ic_dim;
29 }
30 
52 {
53  public:
54  standard(const std::vector<problem::base_ptr> &probs = std::vector<problem::base_ptr>(), const std::vector<algorithm::base_ptr> &algos = std::vector<algorithm::base_ptr>(), unsigned int seed = 0, unsigned int pop_size = 100);
55 
56  protected:
57  //copy constructor
58  standard(const standard &);
59  problem::base_ptr clone() const;
60  void objfun_impl(fitness_vector &, const decision_vector &) const;
62 
63  private:
64 
65  friend class boost::serialization::access;
66  template <class Archive>
67  void serialize(Archive &ar, const unsigned int)
68  {
69  ar & boost::serialization::base_object<base_stochastic>(*this);
70  ar & m_algos;
71  ar & m_probs;
72  ar & m_pop_size;
73  }
74 
75  void setup(const std::vector<problem::base_ptr> &probs, const std::vector<algorithm::base_ptr> &algos);
76  constraint_vector zero_pad_constraint(const constraint_vector&, problem::base::c_size_type) const;
77 
78  void evaluate_algorithm(unsigned int) const;
79 
80  std::vector<algorithm::base_ptr> m_algos;
81  std::vector<problem::base_ptr> m_probs;
82  unsigned int m_pop_size;
83 
84  // To avoid inefficiency resulted from the decoupled fitness and
85  // constraint computation
86  mutable std::vector<bool> m_is_first_evaluation;
87  mutable std::vector<unsigned int> m_database_seed;
88  mutable std::vector<fitness_vector> m_database_f;
89  mutable std::vector<constraint_vector> m_database_c;
90 };
91 
93 
109 standard::standard(const std::vector<problem::base_ptr> &probs, const std::vector<algorithm::base_ptr> &algos, unsigned int seed, unsigned int pop_size): base_stochastic(1, 1, probs.front()->get_f_dimension(), get_max_c_dimension(probs), get_max_ic_dimension(probs), 0, seed), m_pop_size(pop_size), m_is_first_evaluation(algos.size(), true), m_database_seed(algos.size()), m_database_f(algos.size()), m_database_c(algos.size())
110 {
111  setup(probs, algos);
112 }
113 
115 
120 void standard::setup(const std::vector<problem::base_ptr> &probs, const std::vector<algorithm::base_ptr> &algos)
121 {
122  // Sanity check on the algos and probs
123  if(algos.size() == 0){
124  pagmo_throw(value_error, "Empty algorithm set in race_algo");
125  }
126  for(unsigned int i = 0; i < probs.size(); i++){
127  if(probs[i]->get_f_dimension() > 1){
128  pagmo_throw(value_error, "Racing of multi-objective algorithms is not supported yet");
129  }
130  }
131 
132  // Take snapshots of the supplied algos and problems
133  for(unsigned int i = 0; i < algos.size(); i++){
134  m_algos.push_back(algos[i]->clone());
135  }
136  for(unsigned int i = 0; i < probs.size(); i++){
137  m_probs.push_back(probs[i]->clone());
138  }
139 
140  // Set bounds. Decision variable is simply the index of the selected algorithm
141  set_bounds(0, m_algos.size()-1);
142 }
143 
145 standard::standard(const standard &standard_copy):
146  base_stochastic(1, 1, standard_copy.get_f_dimension(),
147  standard_copy.get_c_dimension(),
148  standard_copy.get_ic_dimension(), 0, standard_copy.m_seed),
149  m_algos(standard_copy.m_algos),
150  m_probs(standard_copy.m_probs),
151  m_pop_size(standard_copy.m_pop_size),
152  m_is_first_evaluation(standard_copy.m_is_first_evaluation),
153  m_database_seed(standard_copy.m_database_seed),
154  m_database_f(standard_copy.m_database_f),
155  m_database_c(standard_copy.m_database_c)
156 {
157  set_bounds(standard_copy.get_lb(), standard_copy.get_ub());
158 }
159 
162 {
163  return problem::base_ptr(new standard(*this));
164 }
165 
167 
172 {
173  evaluate_algorithm(x[0]);
174  f = m_database_f[x[0]];
175 }
176 
178 
183 {
184  evaluate_algorithm(x[0]);
185  c = m_database_c[x[0]];
186 }
187 
189 
195 constraint_vector standard::zero_pad_constraint(const constraint_vector& c, problem::base::c_size_type ic_dim) const
196 {
197  constraint_vector c_padded(get_c_dimension(), 0);
198  c_size_type c_dim = c.size();
199  for(problem::base::c_size_type i = 0; i < c_dim - ic_dim; i++){
200  c_padded[i] = c[i];
201  }
202  // Note that this->get_ic_dimension() must be larger than ic_dim by definition
203  for(problem::base::c_size_type i = c_dim - ic_dim; i < c_dim; i++){
204  c_padded[i + get_ic_dimension() - ic_dim] = c[i];
205  }
206  return c_padded;
207 }
208 
210 
218 void standard::evaluate_algorithm(unsigned int algo_idx) const
219 {
220  if(algo_idx >= m_algos.size()){
221  pagmo_throw(value_error, "Out of bound algorithm index");
222  }
223 
224  // The requested data is ready, nothing to do
225  if(!m_is_first_evaluation[algo_idx] && m_database_seed[algo_idx] == m_seed){
226  return;
227  }
228 
229  // Seeding control
230  for(unsigned int i = 0; i < m_algos.size(); i++){
231  m_algos[i]->reset_rngs(m_seed);
232  }
233  m_drng.seed(m_seed);
234 
235  // Randomly sample a problem if required
236  unsigned int prob_idx;
237  if(m_probs.size() == 1){
238  prob_idx = 0;
239  }
240  else{
241  prob_idx = (unsigned int)(m_drng() * 100000) % m_probs.size();
242  }
243 
244  // Fitness defined as the quality of the champion in the evolved
245  // population, evolved by the selected algorithm
246  population pop(*m_probs[prob_idx], m_pop_size, m_seed);
247  m_algos[algo_idx]->evolve(pop);
248 
249  // Store the data, to be retrieved by objfun_impl() or compute_constraints_impl()
250  m_is_first_evaluation[algo_idx] = false;
251  m_database_seed[algo_idx] = m_seed;
252  m_database_f[algo_idx] = pop.champion().f;
253  m_database_c[algo_idx] = zero_pad_constraint(pop.champion().c, m_probs[prob_idx]->get_ic_dimension());
254 }
255 
256 
257 }
258 
259 
261 
269 race_algo::race_algo(const std::vector<algorithm::base_ptr> &algos, const problem::base &prob, unsigned int pop_size, unsigned int seed): m_pop_size(pop_size), m_seed(seed)
270 {
271  for(unsigned int i = 0; i < algos.size(); i++){
272  m_algos.push_back(algos[i]->clone());
273  }
274  m_probs.push_back(prob.clone());
275 }
276 
278 
286 race_algo::race_algo(const std::vector<algorithm::base_ptr> &algos, const std::vector<problem::base_ptr> &probs, unsigned int pop_size, unsigned int seed): m_pop_size(pop_size), m_seed(seed)
287 {
288  for(unsigned int i = 0; i < algos.size(); i++){
289  m_algos.push_back(algos[i]->clone());
290  }
291  for(unsigned int i = 0; i < probs.size(); i++){
292  m_probs.push_back(probs[i]->clone());
293  }
294 }
295 
297 
310 std::pair<std::vector<unsigned int>, unsigned int> race_algo::run(
311  const unsigned int n_final,
312  const unsigned int min_trials,
313  const unsigned int max_count,
314  double delta,
315  const std::vector<unsigned int> &active_set,
316  const bool race_best,
317  const bool screen_output)
318 {
331  // Construct an internal population, such that the winners of the race in
332  // this population corresponds to the winning algorithm
333  metrics_algos::standard metrics(m_probs, m_algos, m_seed, m_pop_size);
334  population algos_pop(metrics);
335  for(unsigned int i = 0; i < m_algos.size(); i++){
336  decision_vector algo_idx(1);
337  algo_idx[0] = i;
338  algos_pop.push_back(algo_idx);
339  }
340 
341  // Conversion to types that pop_race is familiar with
342  std::vector<population::size_type> pop_race_active_set(active_set.size());
343  for(unsigned int i = 0; i < active_set.size(); i++){
344  pop_race_active_set[i] = active_set[i];
345  }
346 
347  // Run the actual race
348  std::pair<std::vector<population::size_type>, unsigned int> res =
349  algos_pop.race(n_final, min_trials, max_count, delta,
350  pop_race_active_set, race_best, screen_output);
351 
352  // Convert the result to the algo's context
353  std::pair<std::vector<unsigned int>, unsigned int> res_algo_race;
354  res_algo_race.first.clear();
355  for(unsigned int i = 0; i < res.first.size(); i++){
356  res_algo_race.first.push_back(res.first[i]);
357  }
358  res_algo_race.second = res.second;
359 
360  return res_algo_race;
361 }
362 
363 }}}
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
c_size_type get_ic_dimension() const
Return inequality constraints dimension.
race_algo(const std::vector< algorithm::base_ptr > &algos=std::vector< algorithm::base_ptr >(), const problem::base &prob=problem::ackley(), unsigned int pop_size=100, unsigned int seed=0)
Constructor of the racing mechanism for algorithms.
Definition: race_algo.cpp:269
Base problem class.
Definition: problem/base.h:148
Population class.
Definition: population.h:70
rng_double m_drng
Random number generator for double-precision floating point values.
unsigned int m_seed
Seed of the random number generator.
problem::base_ptr clone() const
Clone method.
Definition: race_algo.cpp:161
virtual base_ptr clone() const =0
Clone method.
standard(const std::vector< problem::base_ptr > &probs=std::vector< problem::base_ptr >(), const std::vector< algorithm::base_ptr > &algos=std::vector< algorithm::base_ptr >(), unsigned int seed=0, unsigned int pop_size=100)
Constructor of the performance metrics of algorithms on a single problem.
Definition: race_algo.cpp:109
std::vector< double > fitness_vector
Fitness vector type.
Definition: types.h:42
void objfun_impl(fitness_vector &, const decision_vector &) const
The performance of an algorithm encoded in the fitness function.
Definition: race_algo.cpp:171
c_size_type get_c_dimension() const
Return global constraints dimension.
std::pair< std::vector< unsigned int >, unsigned int > run(const unsigned int n_final, const unsigned int min_trials, const unsigned int max_count, double delta, const std::vector< unsigned int > &, const bool race_best, const bool screen_output)
Juice of racing mechanisms for algorithms.
Definition: race_algo.cpp:310
std::vector< double > constraint_vector
Constraint vector type.
Definition: types.h:44
const decision_vector & get_ub() const
Upper bounds getter.
Base Stochastic Optimization Problem.
void compute_constraints_impl(constraint_vector &, const decision_vector &) const
The performance of an algorithm in terms of a constraint vector.
Definition: race_algo.cpp:182
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
const decision_vector & get_lb() const
Lower bounds getter.
void set_bounds(const decision_vector &, const decision_vector &)
Bounds setter from pagmo::decision_vector.