25 #include "sa_corana.h"
26 #include <boost/random/uniform_int.hpp>
27 #include <boost/random/uniform_real.hpp>
30 namespace pagmo {
namespace algorithm {
45 sa_corana::sa_corana(
int niter,
const double &Ts,
const double &Tf,
int niterT,
int niterR,
const double &range):
46 base(),m_niter(niter),m_Ts(Ts),m_Tf(Tf),m_step_adj(niterT),m_bin_size(niterR),m_range(range)
49 pagmo_throw(value_error,
"number of iterations must be nonnegative");
51 if (Ts <= 0 || Tf <= 0 || Ts <= Tf) {
52 pagmo_throw(value_error,
"temperatures must be positive and Ts must be greater than Tf");
55 pagmo_throw(value_error,
"number of iteration before adjusting the temperature must be positive");
58 pagmo_throw(value_error,
"number of iteration before adjusting the neighbourhood must be positive");
60 if (range < 0 || range >1) {
61 pagmo_throw(value_error,
"Initial range must be between 0 and 1");
90 pagmo_throw(value_error,
"There is no continuous part in the problem decision vector for sa_corana to optimise");
93 if ( prob_c_dimension != 0 ) {
94 pagmo_throw(value_error,
"The problem is not box constrained and sa_corana is not suitable to solve it");
97 if ( prob_f_dimension != 1 ) {
98 pagmo_throw(value_error,
"The problem is not single objective and sa_corana is not suitable to solve it");
102 const size_t n_T = m_niter / (m_step_adj * m_bin_size * Dc);
105 if (NP == 0 || m_niter == 0) {
109 pagmo_throw(value_error,
"n_T is zero, increase niter");
113 const int bestidx = pop.get_best_idx();
117 const double Tcoeff = std::pow(m_Tf/m_Ts,1.0/(
double)(n_T));
125 std::vector<int> acp(D,0) ;
126 double ratio = 0, currentT = m_Ts, probab = 0;
129 for (
size_t jter = 0; jter < n_T; ++jter) {
130 for (
int mter = 0; mter < m_step_adj; ++mter) {
131 for (
int kter = 0; kter < m_bin_size; ++kter) {
132 size_t nter = boost::uniform_int<int>(0,Dc-1)(
m_urng);
133 for (
size_t numb = 0; numb < Dc ; ++numb) {
134 nter = (nter + 1) % Dc;
137 xNEW[nter] = xOLD[nter] + boost::uniform_real<double>(-1,1)(
m_drng) * step[nter] * (ub[nter]-lb[nter]);
140 if ((xNEW[nter] > ub[nter]) || (xNEW[nter] < lb[nter])) {
141 xNEW[nter]=xOLD[nter];
150 xOLD[nter] = xNEW[nter];
155 probab = exp ( - fabs(fOLD[0] - fNEW[0] ) / currentT );
159 xOLD[nter] = xNEW[nter];
163 xNEW[nter] = xOLD[nter];
169 for (
size_t iter = 0; iter < Dc; ++iter) {
170 ratio = (double)acp[iter]/(
double)m_bin_size;
174 step[iter] = step [iter] * (1 + 2 *(ratio - .6)/.4);
178 step [iter]= step [iter] / (1 + 2 * ((.4 - ratio)/.4));
182 if ( step[iter] > m_range ) {
183 step [iter] = m_range;
191 pop.set_x(bestidx,xOLD);
192 std::transform(xOLD.begin(), xOLD.end(), pop.
get_individual(bestidx).
cur_x.begin(), xOLD.begin(),std::minus<double>());
193 pop.set_v(bestidx,xOLD);
201 return "Simulated Annealing (Corana's)";
210 std::ostringstream s;
211 s <<
"iter:" << m_niter <<
' ';
212 s <<
"Ts:" << m_Ts <<
' ';
213 s <<
"Tf:" << m_Tf <<
' ';
214 s <<
"steps:" << m_step_adj <<
' ';
215 s <<
"bin_size:" << m_bin_size <<
' ';
216 s <<
"range:" << m_range <<
' ';
boost::shared_ptr< base > base_ptr
Alias for shared pointer to base algorithm.
std::vector< double > decision_vector
Decision vector type.
fitness_vector cur_f
Current fitness vector.
const individual_type & get_individual(const size_type &) const
Get constant reference to individual at position n.
sa_corana(int niter=1, const double &Ts=10, const double &Tf=.1, int m_step_adj=1, int m_bin_size=20, const double &range=1)
Constructor.
std::string human_readable_extra() const
Extra human readable algorithm info.
size_type get_dimension() const
Return global dimension.
bool compare_fitness(const fitness_vector &, const fitness_vector &) const
Compare fitness vectors.
base_ptr clone() const
Clone method.
fitness_vector objfun(const decision_vector &) const
Return fitness of pagmo::decision_vector.
Simulated Annealing, Corana's version with adaptive neighbourhood.
size_type get_i_dimension() const
Return integer dimension.
std::vector< double > fitness_vector
Fitness vector type.
void evolve(population &) const
Evolve implementation.
c_size_type get_c_dimension() const
Return global constraints dimension.
const decision_vector & get_ub() const
Upper bounds getter.
container_type::size_type size_type
Population size type.
decision_vector cur_x
Current decision vector.
rng_uint32 m_urng
Random number generator for unsigned integer values.
f_size_type get_f_dimension() const
Return fitness dimension.
std::string get_name() const
Algorithm name.
const decision_vector & get_lb() const
Lower bounds getter.
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.