PaGMO  1.1.5
ihs.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 <boost/numeric/conversion/cast.hpp>
26 #include <boost/random/uniform_int.hpp>
27 #include <boost/random/uniform_real.hpp>
28 #include <climits>
29 #include <cmath>
30 #include <cstddef>
31 #include <sstream>
32 #include <string>
33 #include <vector>
34 
35 #include "../exceptions.h"
36 #include "../population.h"
37 #include "../problem/base.h"
38 #include "../types.h"
39 #include "base.h"
40 #include "ihs.h"
41 
42 namespace pagmo
43 {
44 namespace algorithm {
45 
47 
59 ihs::ihs(int iterations, const double &phmcr, const double &ppar_min, const double &ppar_max, const double &bw_min, const double &bw_max):
60  base(),m_gen(boost::numeric_cast<std::size_t>(iterations)),m_phmcr(phmcr),m_ppar_min(ppar_min),m_ppar_max(ppar_max),m_bw_min(bw_min),m_bw_max(bw_max)
61 {
62  if (phmcr > 1 || phmcr < 0 || ppar_min > 1 || ppar_min < 0 || ppar_max > 1 || ppar_max < 0) {
63  pagmo_throw(value_error,"probability of choosing from memory and pitch adjustment rates must be in the [0,1] range");
64  }
65  if (ppar_min > ppar_max) {
66  pagmo_throw(value_error,"minimum pitch adjustment rate must not be greater than maximum pitch adjustment rate");
67  }
68  if (bw_min <= 0 || bw_max < bw_min) {
69  pagmo_throw(value_error,"bandwidth values must be positive, and minimum bandwidth must not be greater than maximum bandwidth");
70  }
71 }
72 
74 {
75  return base_ptr(new ihs(*this));
76 }
77 
78 void ihs::evolve(population &pop) const
79 {
80  // Let's store some useful variables.
81  const problem::base &prob = pop.problem();
82  const problem::base::size_type prob_dimension = prob.get_dimension(), prob_i_dimension = prob.get_i_dimension();
83  const decision_vector &lb = prob.get_lb(), &ub = prob.get_ub();
84  const population::size_type pop_size = pop.size();
85  // Get out if there is nothing to do.
86  if (pop_size == 0 || m_gen == 0) {
87  return;
88  }
89  decision_vector lu_diff(prob_dimension);
90  for (problem::base::size_type i = 0; i < prob_dimension; ++i) {
91  lu_diff[i] = ub[i] - lb[i];
92  }
93  // Int distribution to be used when picking random individuals.
94  boost::uniform_int<population::size_type> uni_int(0,pop_size - 1);
95  const double c = std::log(m_bw_min/m_bw_max) / m_gen;
96  // Temporary individual used during evolution.
98  tmp.cur_x.resize(prob_dimension);
99  tmp.cur_f.resize(prob.get_f_dimension());
100  tmp.cur_c.resize(prob.get_c_dimension());
101  for (std::size_t g = 0; g < m_gen; ++g) {
102  const double ppar_cur = m_ppar_min + ((m_ppar_max - m_ppar_min) * g) / m_gen, bw_cur = m_bw_max * std::exp(c * g);
103  // Continuous part.
104  for (problem::base::size_type i = 0; i < prob_dimension - prob_i_dimension; ++i) {
105  if (m_drng() < m_phmcr) {
106  // tmp's i-th chromosome element is the one from a randomly chosen individual.
107  tmp.cur_x[i] = pop.get_individual(uni_int(m_urng)).cur_x[i];
108  // Do pitch adjustment with ppar_cur probability.
109  if (m_drng() < ppar_cur) {
110  // Randomly, add or subtract pitch from the current chromosome element.
111  if (m_drng() > .5) {
112  tmp.cur_x[i] += m_drng() * bw_cur * lu_diff[i];
113  } else {
114  tmp.cur_x[i] -= m_drng() * bw_cur * lu_diff[i];
115  }
116  // Handle the case in which we added or subtracted too much and ended up out
117  // of boundaries.
118  if (tmp.cur_x[i] > ub[i]) {
119  tmp.cur_x[i] = boost::uniform_real<double>(lb[i],ub[i])(m_drng);
120  } else if (tmp.cur_x[i] < lb[i]) {
121  tmp.cur_x[i] = boost::uniform_real<double>(lb[i],ub[i])(m_drng);
122  }
123  }
124  } else {
125  // Pick randomly within the bounds.
126  tmp.cur_x[i] = boost::uniform_real<double>(lb[i],ub[i])(m_drng);
127  }
128  }
129 
130  //Integer Part
131  for (problem::base::size_type i = prob_dimension - prob_i_dimension; i < prob_dimension; ++i) {
132  if (m_drng() < m_phmcr) {
133  tmp.cur_x[i] = pop.get_individual(uni_int(m_urng)).cur_x[i];
134  if (m_drng() < ppar_cur) {
135  if (m_drng() > .5) {
136  tmp.cur_x[i] += double_to_int::convert(m_drng() * bw_cur * lu_diff[i]);
137  } else {
138  tmp.cur_x[i] -= double_to_int::convert(m_drng() * bw_cur * lu_diff[i]);
139  }
140  // Wrap over in case we went past the bounds.
141  if (tmp.cur_x[i] > ub[i]) {
142  tmp.cur_x[i] = lb[i] + double_to_int::convert(tmp.cur_x[i] - ub[i]) % static_cast<int>(lu_diff[i]);
143  } else if (tmp.cur_x[i] < lb[i]) {
144  tmp.cur_x[i] = ub[i] - double_to_int::convert(lb[i] - tmp.cur_x[i]) % static_cast<int>(lu_diff[i]);
145  }
146  }
147  } else {
148  // Pick randomly within the bounds.
149  tmp.cur_x[i] = boost::uniform_int<int>(lb[i],ub[i])(m_urng);
150  }
151  }
152  // And we push him back
153  pop.push_back(tmp.cur_x);
154  // We locate the worst individual.
155  const population::size_type worst_idx = pop.get_worst_idx();
156  // And we get rid of him :)
157  pop.erase(worst_idx);
158  }
159 }
160 
161 
163 std::string ihs::get_name() const
164 {
165  return "Improved Harmony Search";
166 }
167 
169 
172 std::string ihs::human_readable_extra() const
173 {
174  std::ostringstream s;
175  s << "iter:" << m_gen << ' ';
176  s << "phmcr:" << m_phmcr << ' ';
177  s << "ppar_min:" << m_ppar_min << ' ';
178  s << "ppar_max:" << m_ppar_max << ' ';
179  s << "bw_min:" << m_bw_min << ' ';
180  s << "bw_max:" << m_bw_max << ' ';
181  return s.str();
182 }
183 
184 }
185 }
186 
187 BOOST_CLASS_EXPORT_IMPLEMENT(pagmo::algorithm::ihs)
boost::shared_ptr< base > base_ptr
Alias for shared pointer to base algorithm.
Root PaGMO namespace.
std::vector< double > decision_vector
Decision vector type.
Definition: types.h:40
ihs(int gen=1, const double &phmcr=0.85, const double &ppar_min=0.35, const double &ppar_max=0.99, const double &bw_min=1E-5, const double &bw_max=1)
Constructor.
Definition: ihs.cpp:59
fitness_vector cur_f
Current fitness vector.
Definition: population.h:89
const individual_type & get_individual(const size_type &) const
Get constant reference to individual at position n.
Definition: population.cpp:277
Base algorithm class.
void evolve(population &) const
Evolve method.
Definition: ihs.cpp:78
constraint_vector cur_c
Current constraint vector.
Definition: population.h:87
Individuals stored in the population.
Definition: population.h:80
STL namespace.
Base problem class.
Definition: problem/base.h:148
Population class.
Definition: population.h:70
size_type get_dimension() const
Return global dimension.
size_type get_i_dimension() const
Return integer dimension.
std::string human_readable_extra() const
Extra human readable algorithm info.
Definition: ihs.cpp:172
c_size_type get_c_dimension() const
Return global constraints dimension.
const decision_vector & get_ub() const
Upper bounds getter.
base_ptr clone() const
Clone method.
Definition: ihs.cpp:73
container_type::size_type size_type
Population size type.
Definition: population.h:192
decision_vector cur_x
Current decision vector.
Definition: population.h:83
std::string get_name() const
Algorithm name.
Definition: ihs.cpp:163
rng_uint32 m_urng
Random number generator for unsigned integer values.
f_size_type get_f_dimension() const
Return fitness dimension.
const decision_vector & get_lb() const
Lower bounds getter.
Improved harmony search algorithm.
Definition: ihs.h:62
rng_double m_drng
Random number generator for double-precision floating point values.
decision_vector::size_type size_type
Problem's size type: the same as pagmo::decision_vector's size type.
Definition: problem/base.h:160