/* _________________________________________________________________________ * * Coliny: A Library of COLIN optimizers * Copyright (c) 2003, Sandia National Laboratories. * This software is distributed under the GNU Lesser General Public License. * For more information, see the README.html file in the top Coliny directory. * _________________________________________________________________________ */ /** * \file DomainOpsIntArray.h * * Defines the coliny::DomainOpsIntArray class. */ #ifndef coliny_DomainIntOpsArray_h #define coliny_DomainIntOpsArray_h #include #include #include #include #include #define INT_ARRAY_MUTATION_UNIFORM 1 #define INT_ARRAY_MUTATION_INTERVAL 2 namespace coliny { using utilib::ParameterSet; template class DomainOpsIntArray : public DomainOpsArray { public: /// typedef typename DomainOpsArray::info_t info_t; /// typedef typename DomainOpsArray::point_t point_t; /// DomainOpsIntArray(); /// void reset(); /// template void initialize(ProblemT& problem, unsigned int popsize_,double xover_rate, double m_rate) { DomainOpsArray::initialize( problem.num_int_params(), popsize_, xover_rate, m_rate); if ((problem.num_int_params() > 0) && (problem.enforcing_bounds())) { problem.get_int_bounds(lower,upper); lbound_type.resize(lower.size()); ubound_type.resize(lower.size()); range.resize(lower.size()); for (unsigned int i=0; invars; j++) point[j] = utilib::Discretize(this->rnd(),lower[j],upper[j]); } /// point_t lower; /// point_t upper; /// point_t range; /// colin::BoundTypeArray lbound_type; /// colin::BoundTypeArray ubound_type; protected: /// int mutation_range; /// void mutate_value(int i, int& val, info_t& info); }; template DomainOpsIntArray::DomainOpsIntArray() { this->crossover_blocksize=1; ParameterSet::create_categorized_parameter("intarray_xover_blocksize", this->crossover_blocksize, "","1", "Block size used with array-based two-point and uniform crossover", "Crossover"); this->crossover_str="twopoint"; ParameterSet::create_categorized_parameter("intarray_xover_type", this->crossover_str, "","twopoint", "Crossover type\n\ \t onepoint - standard one-point mutation\n\ \t twopoint - standard two-point mutation\n\ \t uniform - standard uniform mutation", "Crossover"); this->mutation_str = "uniform"; ParameterSet::create_categorized_parameter("intarray_mutation_type", this->mutation_str, "","uniform", "Integer mutation type\n\ \t uniform - replace the value with a uniformly random variable\n\ \t interval - replace the value with a uniform value in a local interval", "Mutation"); this->mutation_range=1; ParameterSet::create_categorized_parameter("intarray_mutation_range", this->mutation_range, "","1", "Range of mutation used for 'interval' mutation", "Mutation"); this->mutate_independently=false; ParameterSet::create_categorized_parameter("intarray_mutate_independently", this->mutate_independently, "","false", "If true, then only mutate a single dimension. Note that if this\n\ \tvalue is true, then a single dimension is always mutated, so the\n\ \tmutation allele rate is ignored.", "Mutation"); this->mutation_allele_rate=1.0; ParameterSet::create_categorized_parameter("intarray_mutation_allele_rate", this->mutation_allele_rate, "","1.0", "The probability that any given dimension of the intarray is mutated\n\tgiven that the individual is mutated", "Mutation"); } template void DomainOpsIntArray::reset() { DomainOpsArray::reset(); if ((this->mutation_str == "uniform") || (this->mutation_str == "offset_uniform")) { this->mutation_type = INT_ARRAY_MUTATION_UNIFORM; this->mutation_allele_rate = (this->mutation_allele_rate < 0.0 ? sqrt(M_E/(double)this->nvars)/(double)this->popsize : this->mutation_allele_rate); } else if ((this->mutation_str == "interval") || (this->mutation_str == "replace_uniform")) { this->mutation_type = INT_ARRAY_MUTATION_INTERVAL; this->mutation_allele_rate = (this->mutation_allele_rate < 0.0 ? sqrt(M_E/(double)this->nvars)/(double)this->popsize : this->mutation_allele_rate); } else EXCEPTION_MNGR(std::runtime_error,"DomainOpsIntArray::reset - bad mutation type: \"" << this->mutation_str << "\".\n\t\tValid types are uniform and interval\n"); if (this->crossover_str == "none") this->crossover_type = ARRAY_XOVER_NONE; else if (this->crossover_str == "twopoint") this->crossover_type = ARRAY_XOVER_TWOPOINT; else if (this->crossover_str == "uniform") this->crossover_type = ARRAY_XOVER_UNIFORM; else EXCEPTION_MNGR(std::runtime_error, "DomainOpsIntArray::reset -- bad xover type: \"" << this->crossover_str << "\".\n\t\tValid types are twopoint and uniform\n"); } template void DomainOpsIntArray::mutate_value(int i, int& value, info_t& info) { switch (this->mutation_type) { case INT_ARRAY_MUTATION_INTERVAL: value = utilib::Discretize(this->rnd(),lower[i],upper[i]); break; case INT_ARRAY_MUTATION_UNIFORM: int tmp = utilib::Discretize(this->rnd(), std::max(lower[i],value-mutation_range), std::min(upper[i]-1,value+mutation_range-1)); value = (tmp < value ? tmp : tmp+1); break; }; if (value > upper[i]) { if (ubound_type[i] == colin::hard_bound) value = upper[i]; else if (ubound_type[i] == colin::periodic_bound) while (value > upper[i]) value -= range[i]; } if (value < lower[i]) { if (lbound_type[i] == colin::hard_bound) value = lower[i]; else if (lbound_type[i] == colin::periodic_bound) while (value < lower[i]) value += range[i]; } } } #endif