PaGMO  1.1.5
antibodies_problem.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 "base.h"
32 #include "antibodies_problem.h"
33 
34 namespace pagmo { namespace problem {
46  base((int)problem.get_dimension(),
47  problem.get_i_dimension(),
48  problem.get_f_dimension(),
49  0,
50  0,
51  0.),
52  m_original_problem(problem.clone()),
53  m_pop_antigens(),
54  m_method(method)
55 {
56  if(m_original_problem->get_c_dimension() <= 0){
57  pagmo_throw(value_error,"The original problem has no constraints.");
58  }
59 
60  // check that the dimension of the problem is 1
61  if(m_original_problem->get_f_dimension() != 1) {
62  pagmo_throw(value_error,"The original fitness dimension of the problem must be one, multi objective problems can't be handled with co-evolution meta problem.");
63  }
64 
65  // encoding for hamming distance
66  m_bit_encoding = 25;
67  m_max_encoding_integer = int(std::pow(2., m_bit_encoding));
68 
69  set_bounds(m_original_problem->get_lb(),m_original_problem->get_ub());
70 }
71 
74  base((int)prob.get_dimension(),
75  prob.get_i_dimension(),
76  prob.get_f_dimension(),
77  prob.get_c_dimension(),
78  prob.get_ic_dimension(),
79  prob.get_c_tol()),
80  m_original_problem(prob.m_original_problem->clone()),
81  m_pop_antigens(prob.m_pop_antigens),
82  m_method(prob.m_method),
83  m_bit_encoding(prob.m_bit_encoding),
84  m_max_encoding_integer(prob.m_max_encoding_integer)
85 {
86  set_bounds(m_original_problem->get_lb(),m_original_problem->get_ub());
87 }
88 
91 {
92  return base_ptr(new antibodies_problem(*this));
93 }
94 
97 
101 {
102  // compute the fitness which is the distance to the current population
103  f[0] = compute_distance(x);
104 }
105 
107 
112 {
113  return m_original_problem->compare_fitness(v_f1,v_f2);
114 }
115 
117 
121 {
122  std::ostringstream oss;
123  oss << m_original_problem->human_readable_extra() << std::endl;
124  oss << "\n\tWith antibodies method";
125  oss << std::endl;
126  return oss.str();
127 }
128 
129 std::string antibodies_problem::get_name() const
130 {
131  return m_original_problem->get_name() + " [antibodies_problem]";
132 }
133 
135 
138 void antibodies_problem::set_antigens(const std::vector<decision_vector> &pop_antigens)
139 {
140  if(pop_antigens.size() == 0) {
141  pagmo_throw(value_error,"The size of the antigens population must be different from 0.");
142  }
143  m_pop_antigens = pop_antigens;
144 }
145 
147 
150 double antibodies_problem::compute_distance(const decision_vector &x) const {
151  double distance = 0.;
152 
153  // hamming distance
154 
155  switch(m_method) {
156  case(algorithm::cstrs_immune_system::HAMMING): {
157  const decision_vector &lb = get_lb();
158  const decision_vector &ub = get_ub();
159 
160  for(decision_vector::size_type i=0; i<x.size(); i++) {
161 
162  std::vector<int> current_binary_gene = double_to_binary(x.at(i), lb.at(i), ub.at(i));
163 
164  for(decision_vector::size_type j=0; j<m_pop_antigens.size(); j++) {
165 
166  std::vector<int> antigens_binary_gene = double_to_binary((m_pop_antigens.at(j)).at(i), lb.at(i), ub.at(i));
167 
168  for(std::vector<int>::size_type k=0; k<antigens_binary_gene.size(); k++) {
169  distance += antigens_binary_gene.at(k) && current_binary_gene.at(k);
170  }
171  }
172  }
173 
174  // we take the inverse of the distance as the measure we need is
175  // how close the x is from the antigen population
176  // which means that we need to maximize the ressemblance
177  distance = - distance;
178  break;
179  }
180  case(algorithm::cstrs_immune_system::EUCLIDEAN): {
181  for(decision_vector::size_type j=0; j<m_pop_antigens.size(); j++) {
182 
183  double euclid = 0.;
184  const decision_vector &antigen_decision = m_pop_antigens.at(j);
185 
186  for(decision_vector::size_type i=0; i<x.size(); i++) {
187  euclid += std::pow(x.at(i) - antigen_decision.at(i),2);
188  }
189  distance += std::sqrt(euclid);
190  }
191 
192  break;
193  }
194  }
195 
196  return distance;
197 }
198 
200 
207 std::vector<int> antibodies_problem::double_to_binary(const double &number, const double &lb, const double &ub) const
208 {
209  // initialize the vector of size m_bit_encoding
210  std::vector<int> binary(m_bit_encoding, 0);
211 
212  // convert the current number into its binary representation considering the domain
213  // available
214  int temp_number = (number - lb) * (m_max_encoding_integer - 1) / (ub - lb) ;
215 
216  // store the binary number
217  int position = 0;
218  while (temp_number!=0)
219  {
220  if( (temp_number % 2) == 0 ) {
221  binary[position] = 0;
222  } else {
223  binary[position] = 1;
224  }
225  temp_number = (int)std::floor(temp_number/2);
226  position++;
227  }
228  // reverse the order as this algorithm provides the reverse binary reprentation
229  std::reverse(binary.begin(),binary.end());
230 
231  return binary;
232 }
233 
234 }}
235 
236 BOOST_CLASS_EXPORT_IMPLEMENT(pagmo::problem::antibodies_problem)
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
base_ptr clone() const
Clone method.
Base problem class.
Definition: problem/base.h:148
antibodies_problem(const base &=cec2006(4), const algorithm::cstrs_immune_system::distance_method_type=algorithm::cstrs_immune_system::HAMMING)
distance_method_type
Type of antibodies problem distance method.
void objfun_impl(fitness_vector &, const decision_vector &) const
void set_antigens(const std::vector< decision_vector > &)
Updates the antigens population used to compute the fitness.
std::vector< double > fitness_vector
Fitness vector type.
Definition: types.h:42
const decision_vector & get_ub() const
Upper bounds getter.
bool compare_fitness_impl(const fitness_vector &, const fitness_vector &) const
Implementation of fitness vectors comparison.
std::string human_readable_extra() const
Extra human readable info for the problem.
const decision_vector & get_lb() const
Lower bounds getter.
void set_bounds(const decision_vector &, const decision_vector &)
Bounds setter from pagmo::decision_vector.
std::string get_name() const
Get problem's name.