PaGMO  1.1.5
robust.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 <cmath>
26 #include <iostream>
27 #include <boost/functional/hash.hpp>
28 
29 #include "../exceptions.h"
30 #include "../types.h"
31 #include "base.h"
32 #include "robust.h"
33 
34 using namespace std;
35 
36 namespace pagmo { namespace problem {
37 
49 robust::robust(const base & p, unsigned int trials, const double param_rho, unsigned int seed):
50  base_stochastic((int)p.get_dimension(),
51  p.get_i_dimension(),
52  p.get_f_dimension(),
53  p.get_c_dimension(),
54  p.get_ic_dimension(),
55  p.get_c_tol(), seed),
56  m_original_problem(p.clone()),
57  m_normal_dist(0, 1),
58  m_uniform_dist(0, 1),
59  m_trials(trials),
60  m_rho(param_rho)
61 {
62  if(param_rho < 0){
63  pagmo_throw(value_error, "Rho should be greater than 0");
64  }
65  set_bounds(p.get_lb(),p.get_ub());
66 }
67 
69 robust::robust(const robust &prob):
70  base_stochastic(prob),
71  m_original_problem(prob.m_original_problem->clone()),
72  m_uniform_dist(0, prob.m_rho),
73  m_trials(prob.m_trials),
74  m_rho(prob.m_rho) {}
75 
78 {
79  return base_ptr(new robust(*this));
80 }
81 
88 void robust::set_rho(double rho)
89 {
90  m_rho = rho;
91 }
92 
96 double robust::get_rho() const
97 {
98  return m_rho;
99 }
100 
104 {
105  // Temporary storage used for averaging
106  fitness_vector tmp(f.size(),0.0);
107  f = tmp;
108 
109  // Set the seed
110  m_drng.seed(m_seed);
111 
112  // Perturb decision vector and evaluate
113  decision_vector x_perturbed(x);
114  for(unsigned int i = 0; i < m_trials; ++i){
115  inject_noise_x(x_perturbed);
116  m_original_problem->objfun(tmp, x_perturbed);
117  for(fitness_vector::size_type j = 0; j < f.size(); ++j){
118  f[j] += tmp[j] / (double)m_trials;
119  }
120  }
121 }
122 
126 {
127  // Temporary storage used for averaging
128  constraint_vector tmp(c.size(), 0.0);
129  c = tmp;
130 
131  // Set the seed
132  m_drng.seed(m_seed);
133 
134  // Perturb decision vector and evaluate
135  decision_vector x_perturbed(x);
136  for(unsigned int i = 0; i < m_trials; ++i){
137  inject_noise_x(x_perturbed);
138  m_original_problem->compute_constraints(tmp, x_perturbed);
139  for(constraint_vector::size_type j = 0; j < c.size(); ++j){
140  c[j] = tmp[j] / (double)m_trials;
141  }
142  }
143 }
144 
146 void robust::inject_noise_x(decision_vector &x) const
147 {
148  // We follow the algorithm at
149  // http://math.stackexchange.com/questions/87230/picking-random-points-in-the-volume-of-sphere-with-uniform-probability
150 
151  // 0. Define the radius
152  double radius = m_rho * pow(m_uniform_dist(m_drng),1.0/x.size());
153 
154  // 1. Sampling N(0,1) on each dimension
155  std::vector<double> perturbation(x.size(), 0.0);
156  double c2=0;
157  for(size_type i = 0; i < perturbation.size(); i++){
158  perturbation[i] = m_normal_dist(m_drng);
159  c2 += perturbation[i]*perturbation[i];
160  }
161 
162  // 2. Normalize the vector
163  for(size_type i = 0; i < perturbation.size(); i++){
164  perturbation[i] *= (radius / sqrt(c2) );
165  x[i] += perturbation[i];
166  }
167 
168  // 3. Clip the variables to the valid bounds
169  for(base::size_type i = 0; i < x.size(); i++){
170  x[i] = std::max(x[i], get_lb()[i]);
171  x[i] = std::min(x[i], get_ub()[i]);
172  }
173 }
174 
175 std::string robust::get_name() const
176 {
177  return m_original_problem->get_name() + " [Robust]";
178 }
179 
181 
184 std::string robust::human_readable_extra() const
185 {
186  std::ostringstream oss;
187  oss << m_original_problem->human_readable_extra() << std::endl;
188  oss << "\tNeighbourhood radius = " << m_rho;
189  oss << "\n\ttrials: "<<m_trials;
190  oss << "\n\tseed: "<<m_seed<< std::endl;
191  return oss.str();
192 }
193 }}
194 
195 BOOST_CLASS_EXPORT_IMPLEMENT(pagmo::problem::robust)
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 objfun_impl(fitness_vector &, const decision_vector &) const
Definition: robust.cpp:103
STL namespace.
std::string get_name() const
Get problem's name.
Definition: robust.cpp:175
Base problem class.
Definition: problem/base.h:148
rng_double m_drng
Random number generator for double-precision floating point values.
double get_rho() const
Definition: robust.cpp:96
void set_rho(double)
Definition: robust.cpp:88
unsigned int m_seed
Seed of the random number generator.
robust(const base &=ackley(1), unsigned int trials=1, const double param_rho=0.1, unsigned int seed=0u)
Definition: robust.cpp:49
std::vector< double > fitness_vector
Fitness vector type.
Definition: types.h:42
Robust meta-problem.
Definition: robust.h:51
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
Definition: robust.cpp:125
const decision_vector & get_lb() const
Lower bounds getter.
base_ptr clone() const
Clone method.
Definition: robust.cpp:77
void set_bounds(const decision_vector &, const decision_vector &)
Bounds setter from pagmo::decision_vector.
decision_vector::size_type size_type
Problem's size type: the same as pagmo::decision_vector's size type.
Definition: problem/base.h:160
std::string human_readable_extra() const
Extra human readable info for the problem.
Definition: robust.cpp:184