//----------------------------------------------------------------------------- // eoLottery.h //----------------------------------------------------------------------------- #ifndef eoLottery_h #define eoLottery_h //----------------------------------------------------------------------------- #include // MINFLOAT #include // accumulate #include // eoPop eoSelect //----------------------------------------------------------------------------- /// eoLottery: a selection method. /// requires that the fitness type of the chromosome inherits from eoFitness /// or have a cast to float implemented //----------------------------------------------------------------------------- template class eoLottery: public eoSelect { public: /// (Default) Constructor. eoLottery(const float& _rate = 1.0): rate(_rate) {} /// void operator()(const eoPop& pop, eoPop& breeders) const { // scores of chromosomes vector score(pop.size()); // calculates accumulated scores for chromosomes for (unsigned i = 0; i < pop.size(); i++) score[i] = pop[i].fitness(); float sum = accumulate(score.begin(), score.end(), MINFLOAT); transform(score.begin(), score.end(), score.begin(), bind2nd(divides(), sum)); partial_sum(score.begin(), score.end(), score.begin()); // generates random numbers vector random(pop.size()); generate(random.begin(), random.end(), eoUniform(0,1)); sort(random.begin(), random.end(), less()); // selection of chromosomes unsigned score_index = 0; // position in score vector unsigned random_index = 0; // position in random vector unsigned num_chroms = (unsigned)(rate * pop.size()); do { if(random[random_index] < score[score_index]) { breeders.push_back(pop[score_index]); random_index++; } else if (score_index < pop.size()) score_index++; else fill_n(back_insert_iterator >(breeders), num_chroms - breeders.size(), pop.back()); } while (breeders.size() < num_chroms); } private: float rate; // selection rate }; //----------------------------------------------------------------------------- #endif eoLottery_h