28 #include "../exceptions.h"
30 #include "../population.h"
31 #include "cstrs_self_adaptive.h"
36 namespace pagmo {
namespace problem {
49 cstrs_self_adaptive::cstrs_self_adaptive(
const base &problem,
const population &pop):
52 problem.get_dimension(),
53 problem.get_i_dimension(),
54 problem.get_f_dimension(),
57 std::vector<double>()),
58 m_apply_penalty_1(false),
59 m_scaling_factor(0.0),
60 m_c_scaling(problem.get_c_dimension(),0.0),
61 m_f_hat_down(problem.get_f_dimension(),0.0),
62 m_f_hat_up(problem.get_f_dimension(),0.0),
63 m_f_hat_round(problem.get_f_dimension(),0.0),
69 m_decision_vector_hash()
71 if(m_original_problem->get_c_dimension() <= 0){
72 pagmo_throw(value_error,
"The original problem has no constraints.");
76 if (m_original_problem->get_f_dimension() != 1) {
77 pagmo_throw(value_error,
"The original fitness dimension of the problem must be one, multi objective problems can't be handled with self adaptive meta problem.");
80 if(problem != pop.problem()) {
81 pagmo_throw(value_error,
"The problem linked to the population is not the same as the problem given in argument.");
84 update_penalty_coeff(pop);
90 problem.get_dimension(),
91 problem.get_i_dimension(),
92 problem.get_f_dimension(),
95 std::vector<double>()),
96 m_apply_penalty_1(false),
97 m_scaling_factor(0.0),
98 m_c_scaling(problem.get_c_dimension(),0.0),
99 m_f_hat_down(problem.get_f_dimension(),0.0),
100 m_f_hat_up(problem.get_f_dimension(),0.0),
101 m_f_hat_round(problem.get_f_dimension(),0.0),
107 m_decision_vector_hash()
109 population pop(*m_original_problem,0);
111 if(m_original_problem->get_c_dimension() <= 0){
112 pagmo_throw(value_error,
"The original problem has no constraints.");
116 if (m_original_problem->get_f_dimension() != 1) {
117 pagmo_throw(value_error,
"The original fitness dimension of the problem must be one, multi objective problems can't be handled with self adaptive meta problem.");
119 update_penalty_coeff(pop);
135 std::map<std::size_t, fitness_vector>::const_iterator it_f;
136 std::map<std::size_t, constraint_vector>::const_iterator it_c;
138 double solution_infeasibility;
140 it_f = m_map_fitness.find(m_decision_vector_hash(x));
141 if(it_f != m_map_fitness.end()) {
143 it_c = m_map_constraint.find(m_decision_vector_hash(x));
147 solution_infeasibility = compute_solution_infeasibility(it_c->second);
150 m_original_problem->objfun(f, x);
154 m_original_problem->compute_constraints(c,x);
156 solution_infeasibility = compute_solution_infeasibility(c);
159 if(solution_infeasibility > 0.) {
161 if(m_apply_penalty_1) {
162 double inf_tilde = 0.;
163 inf_tilde = (solution_infeasibility - m_i_hat_down) /
164 (m_i_hat_up - m_i_hat_down);
166 f[0] += inf_tilde * (m_f_hat_down[0] - m_f_hat_up[0]);
170 f[0] += m_scaling_factor * std::fabs(f[0]) * ( (std::exp(2. * solution_infeasibility) - 1.) / (std::exp(2.) - 1.) );
180 std::ostringstream oss;
181 oss << m_original_problem->human_readable_extra() << std::endl;
182 oss <<
"\n\tConstraints handled with self-adaptive method ";
189 return m_original_problem->get_name() +
" [cstrs_self_adaptive]";
198 void cstrs_self_adaptive::update_penalty_coeff(
const population &pop)
200 if(*m_original_problem != pop.problem()) {
201 pagmo_throw(value_error,
"The problem linked to the population is not the same as the problem given in argument.");
212 m_map_fitness.clear();
213 m_map_constraint.clear();
216 const population::individual_type ¤t_individual = pop.get_individual(i);
218 m_map_fitness[m_decision_vector_hash(current_individual.cur_x)]=current_individual.cur_f;
219 m_map_constraint[m_decision_vector_hash(current_individual.cur_x)]=current_individual.cur_c;
222 std::vector<population::size_type> feasible_idx(0);
223 std::vector<population::size_type> infeasible_idx(0);
227 const population::individual_type ¤t_individual = pop.get_individual(i);
229 if(m_original_problem->feasibility_c(current_individual.cur_c)) {
230 feasible_idx.push_back(i);
232 infeasible_idx.push_back(i);
237 if(infeasible_idx.size() == 0) {
238 update_c_scaling(pop);
239 m_apply_penalty_1 =
false;
240 m_scaling_factor = 0.;
243 m_apply_penalty_1 =
false;
244 m_scaling_factor = 0.;
247 update_c_scaling(pop);
252 std::vector<double> solution_infeasibility(pop_size);
253 std::fill(solution_infeasibility.begin(),solution_infeasibility.end(),0.);
256 solution_infeasibility.resize(pop_size);
257 std::fill(solution_infeasibility.begin(),solution_infeasibility.end(),0.);
260 const population::individual_type ¤t_individual = pop.get_individual(i);
263 solution_infeasibility[i] = compute_solution_infeasibility(current_individual.cur_c);
272 if(feasible_idx.size() > 0) {
274 hat_down_idx = feasible_idx.at(0);
279 const population::individual_type ¤t_individual = pop.get_individual(current_idx);
281 if(m_original_problem->compare_fitness(current_individual.cur_f, pop.get_individual(hat_down_idx).cur_f)) {
282 hat_down_idx = current_idx;
287 fitness_vector f_hat_down = pop.get_individual(hat_down_idx).cur_f;
291 bool pop_contains_infeasible_f_better_x_hat_down =
false;
294 const population::individual_type ¤t_individual = pop.get_individual(current_idx);
296 if(m_original_problem->compare_fitness(current_individual.cur_f, f_hat_down)) {
297 pop_contains_infeasible_f_better_x_hat_down =
true;
300 hat_up_idx = current_idx;
306 if(pop_contains_infeasible_f_better_x_hat_down) {
312 const population::individual_type ¤t_individual = pop.get_individual(current_idx);
314 if(m_original_problem->compare_fitness(current_individual.cur_f, f_hat_down) &&
315 (solution_infeasibility.at(current_idx) >= solution_infeasibility.at(hat_up_idx)) ) {
317 if(solution_infeasibility.at(current_idx) == solution_infeasibility.at(hat_up_idx)) {
318 if(m_original_problem->compare_fitness(current_individual.cur_f, pop.get_individual(hat_up_idx).cur_f)) {
319 hat_up_idx = current_idx;
322 hat_up_idx = current_idx;
328 m_apply_penalty_1 =
true;
334 hat_up_idx = infeasible_idx.at(0);
338 const population::individual_type ¤t_individual = pop.get_individual(current_idx);
340 if(solution_infeasibility.at(current_idx) >= solution_infeasibility.at(hat_up_idx)) {
341 if(solution_infeasibility.at(current_idx) == solution_infeasibility.at(hat_up_idx)) {
342 if(m_original_problem->compare_fitness(pop.get_individual(hat_up_idx).cur_f, current_individual.cur_f)) {
343 hat_up_idx = current_idx;
346 hat_up_idx = current_idx;
352 m_apply_penalty_1 =
false;
361 const population::individual_type ¤t_individual = pop.get_individual(i);
363 if(solution_infeasibility.at(i) <= solution_infeasibility.at(hat_down_idx)) {
364 if(solution_infeasibility.at(i) == solution_infeasibility.at(hat_down_idx)) {
365 if(m_original_problem->compare_fitness(current_individual.cur_f, pop.get_individual(hat_down_idx).cur_f)) {
376 const population::individual_type ¤t_individual = pop.get_individual(i);
378 if(solution_infeasibility.at(i) >= solution_infeasibility.at(hat_up_idx)) {
379 if(solution_infeasibility.at(i) == solution_infeasibility.at(hat_up_idx)) {
380 if(m_original_problem->compare_fitness(pop.get_individual(hat_up_idx).cur_f, current_individual.cur_f)) {
390 m_apply_penalty_1 =
true;
397 const population::individual_type ¤t_individual = pop.get_individual(i);
399 if(m_original_problem->compare_fitness(pop.get_individual(hat_round_idx).cur_f, current_individual.cur_f)) {
405 m_f_hat_round = pop.get_individual(hat_round_idx).cur_f;
406 m_f_hat_down = pop.get_individual(hat_down_idx).cur_f;
407 m_f_hat_up = pop.get_individual(hat_up_idx).cur_f;
410 m_i_hat_round = solution_infeasibility.at(hat_round_idx);
411 m_i_hat_down = solution_infeasibility.at(hat_down_idx);
412 m_i_hat_up = solution_infeasibility.at(hat_up_idx);
415 m_scaling_factor = 0.;
417 if(m_original_problem->compare_fitness(m_f_hat_down, m_f_hat_up)) {
418 m_scaling_factor = (m_f_hat_round[0] - m_f_hat_up[0]) / m_f_hat_up[0];
420 m_scaling_factor = (m_f_hat_round[0] - m_f_hat_down[0]) / m_f_hat_down[0];
422 if(m_f_hat_up[0] == m_f_hat_round[0]) {
423 m_scaling_factor = 0.;
433 void cstrs_self_adaptive::update_c_scaling(
const population &pop)
435 if(*m_original_problem != pop.problem()) {
436 pagmo_throw(value_error,
"The problem linked to the population is not the same as the problem given in argument.");
446 m_original_problem->get_c_dimension() -
447 m_original_problem->get_ic_dimension();
449 const std::vector<double> &c_tol = m_original_problem->get_c_tol();
451 m_c_scaling.resize(m_original_problem->get_c_dimension());
452 std::fill(m_c_scaling.begin(),m_c_scaling.end(),0.);
457 const population::individual_type ¤t_individual = pop.get_individual(i);
464 m_c_scaling[j] = std::max(m_c_scaling[j], std::max(0., (std::abs(c.at(j)) - c_tol.at(j))) );
467 m_c_scaling[j] = std::max(m_c_scaling[j], std::max(0., c.at(j) - c_tol.at(j)) );
479 double cstrs_self_adaptive::compute_solution_infeasibility(
const constraint_vector &c)
const
484 m_original_problem->get_c_dimension() -
485 m_original_problem->get_ic_dimension();
487 double solution_infeasibility = 0.;
489 const std::vector<double> &c_tol = m_original_problem->get_c_tol();
495 if(m_c_scaling[j] > 0.) {
496 solution_infeasibility += std::max(0.,(std::abs(c.at(j)) - c_tol.at(j))) / m_c_scaling[j];
500 if(m_c_scaling[j] > 0.) {
501 solution_infeasibility += std::max(0.,c.at(j) - c_tol.at(j)) / m_c_scaling[j];
505 solution_infeasibility /= prob_c_dimension;
507 return solution_infeasibility;
513 BOOST_CLASS_EXPORT_IMPLEMENT(pagmo::problem::cstrs_self_adaptive)
boost::shared_ptr< base > base_ptr
Alias for shared pointer to base algorithm.
std::vector< double > decision_vector
Decision vector type.
std::string human_readable_extra() const
Extra human readable algorithm info.
std::vector< double > fitness_vector
Fitness vector type.
std::vector< double > constraint_vector
Constraint vector type.
cstrs_self_adaptive(const base &=jde(), int gen=1, double=1e-15, double=1e-15)
Constructor.
container_type::size_type size_type
Population size type.
constraint_vector::size_type c_size_type
Constraints' size type: the same as pagmo::constraint_vector's size type.
base_ptr clone() const
Clone method.
std::string get_name() const
Algorithm name.