PaGMO  1.1.5
death_penalty.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 <algorithm>
27 
28 #include "../exceptions.h"
29 #include "../types.h"
30 #include "../population.h"
31 #include "death_penalty.h"
32 
33 namespace pagmo { namespace problem {
34 
36 
45 death_penalty::death_penalty(const base &problem, const method_type method, const std::vector<double> & penalty_factors):
46  base_meta(
47  problem,
48  problem.get_dimension(),
49  problem.get_i_dimension(),
50  problem.get_f_dimension(),
51  0,
52  0,
53  std::vector<double>()),
54  m_method(method),
55  m_penalty_factors(penalty_factors)
56 {
57  if(m_original_problem->get_c_dimension() <= 0){
58  pagmo_throw(value_error,"The original problem is unconstrained.");
59  }
60 
61  if( method > 2 || method < 0) {
62  pagmo_throw(value_error, "the death penalty method must be set to 0 for simple death, 1 for Kuri death and 2 for static penalty with predefined penalty coefficients.");
63  }
64 
65  if(method == WEIGHTED && m_penalty_factors.size() != m_original_problem->get_c_dimension()){
66  pagmo_throw(value_error, "the vector of penalties factors is missing or needs to match constraints size");
67  }
68 
69  if(method != WEIGHTED && m_penalty_factors.size() > 0){
70  pagmo_throw(value_error, "Methods which are not WEIGHTED do not make use of weight vectors");
71  }
72 
73 }
74 
77 {
78  return base_ptr(new death_penalty(*this));
79 }
80 
84 {
85  constraint_vector c(m_original_problem->get_c_dimension(),0);
86  m_original_problem->compute_constraints(c,x);
87 
88  if(m_original_problem->feasibility_c(c)) {
89  m_original_problem->objfun(f, x);
90  } else {
91  double high_value = boost::numeric::bounds<double>::highest();
92 
93  switch(m_method)
94  {
95  case SIMPLE:
96  {
97  std::fill(f.begin(),f.end(),high_value);
98  break;
99  }
100  case KURI:
101  {
102  constraint_vector::size_type number_of_constraints = c.size();
103  constraint_vector::size_type number_of_satisfied_constraints = 0;
104 
105  // computes the number of satisfied constraints
106  for(c_size_type i=0; i<number_of_constraints; i++){
107  if(m_original_problem->test_constraint(c,i))
108  number_of_satisfied_constraints += 1;
109  }
110 
111  // sets the Kuri penalization
112  double penalization = high_value * (1. - (double)number_of_satisfied_constraints / (double)number_of_constraints);
113 
114  std::fill(f.begin(),f.end(),penalization);
115  break;
116  }
117  case WEIGHTED:
118  {
119  m_original_problem->objfun(f, x);
120  const std::vector<double> &c_tol = m_original_problem->get_c_tol();
121 
122  // modify equality constraints to behave as inequality constraints:
123  c_size_type number_of_constraints = m_original_problem->get_c_dimension();
124  c_size_type number_of_eq_constraints = number_of_constraints - m_original_problem->get_ic_dimension();
125  double penalization = 0;
126 
127  for(c_size_type i=0; i<number_of_constraints; i++) {
128  if(i<number_of_eq_constraints){
129  c[i] = std::abs(c[i]) - c_tol[i];
130  }
131  else{
132  c[i] = c[i] - c_tol[i];
133  }
134  }
135 
136  for(c_size_type i=0; i<number_of_constraints; i++) {
137  if(c[i] > 0.) {
138  penalization += m_penalty_factors[i]*c[i];
139  }
140  }
141 
142  // penalizing the objective with the sum of the violation, weighted with the given factors
143  for(f_size_type i=0; i<f.size(); i++){
144  f[i] += penalization;
145  }
146 
147  break;
148  }
149  default:
150  pagmo_throw(value_error, "Error: There are only 2 methods for the death penalty!");
151  break;
152  }
153  }
154 }
155 
157 
161 {
162  std::ostringstream oss;
163  oss << m_original_problem->human_readable_extra() << std::endl;
164  oss << "\n\tConstraints handled with death penalty, method ";
165  switch(m_method){
166  case SIMPLE: {
167  oss << "SIMPLE ";
168  break;
169  }
170  case KURI: {
171  oss << "KURI ";
172  break;
173  }
174  case WEIGHTED: {
175  oss << "WEIGHTED ";
176  break;
177  }
178  }
179  oss << std::endl;
180  return oss.str();
181 }
182 
183 std::string death_penalty::get_name() const
184 {
185  std::string method;
186 
187  switch(m_method){
188  case SIMPLE: {
189  method = "SIMPLE ";
190  break;
191  }
192  case KURI: {
193  method = "KURI ";
194  break;
195  }
196  case WEIGHTED: {
197  method = "WEIGHTED ";
198  break;
199  }
200  }
201  return m_original_problem->get_name() + " [death_penalty, method_" + method + "]";
202 }
203 
204 }}
205 
206 BOOST_CLASS_EXPORT_IMPLEMENT(pagmo::problem::death_penalty)
207 
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
std::string get_name() const
Get problem's name.
fitness_vector::size_type f_size_type
Fitness' size type: the same as pagmo::fitness_vector's size type.
Definition: problem/base.h:162
base_ptr clone() const
Clone method.
STL namespace.
Base problem class.
Definition: problem/base.h:148
method_type
Mechanism used to assign the penalty.
Definition: death_penalty.h:58
death_penalty(const base &=cec2006(4), const method_type=SIMPLE, const std::vector< double > &=std::vector< double >())
Constructor from a constrained problem.
Meta=problems base class.
Definition: base_meta.h:50
std::vector< double > fitness_vector
Fitness vector type.
Definition: types.h:42
std::string human_readable_extra() const
Extra human readable info for the problem.
void objfun_impl(fitness_vector &, const decision_vector &) const
std::vector< double > constraint_vector
Constraint vector type.
Definition: types.h:44
Penalizes the fitness function according to the number of satisfied constraints.
Definition: death_penalty.h:60
Penalizes the fitness function with a high value id the decision vector is unfeasible.
Definition: death_penalty.h:59
constraint_vector::size_type c_size_type
Constraints' size type: the same as pagmo::constraint_vector's size type.
Definition: problem/base.h:164
Penalizes the fitness function with the weighted sum of the violations.
Definition: death_penalty.h:61
Constrainted death penalty meta-problem.
Definition: death_penalty.h:54
base_ptr m_original_problem
Smart pointer to the original problem instance.
Definition: base_meta.h:80