123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834 |
- ///
- /// @file jade.cc
- /// @author Ladutenko Konstantin <kostyfisik at gmail (.) com>
- /// @date Thu Aug 15 19:26:53 2013
- /// @copyright 2013 Ladutenko Konstantin
- /// @section LICENSE
- /// This file is part of JADE++.
- ///
- /// JADE++ is free software: you can redistribute it and/or modify
- /// it under the terms of the GNU General Public License as published by
- /// the Free Software Foundation, either version 3 of the License, or
- /// (at your option) any later version.
- ///
- /// JADE++ is distributed in the hope that it will be useful,
- /// but WITHOUT ANY WARRANTY; without even the implied warranty of
- /// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- /// GNU General Public License for more details.
- ///
- /// You should have received a copy of the GNU General Public License
- /// along with JADE++. If not, see <http://www.gnu.org/licenses/>.
- ///
- /// @brief JADE++ is a free (GPLv3+) high performance implementation of
- /// adaptive differential evolution optimization algorithm from
- /// Jingqiao Zhang and Arthur C. Sanderson book 'Adaptive Differential
- /// Evolution. A Robust Approach to Multimodal Problem Optimization'
- /// Springer, 2009. Crossover rate was patched according to PMCRADE
- /// approach supposed by Jie Li, Wujie Zhu, Mengjun Zhou, and Hua Wang
- /// in 'Power Mean Based Crossover Rate Adaptive Differential
- /// Evolution' in H. Deng et al. (Eds.): AICI 2011, Part II, LNAI
- /// 7003, pp. 34–41, 2011
- #include "./jade.h"
- #include <mpi.h>
- #include <random>
- #include <cstdio>
- #include <cmath>
- #include <algorithm>
- #include <map>
- #include <iterator>
- #include <string>
- #include <vector>
- #include <iostream>
- namespace jade {
- /// @todo Replace all simple kError returns with something meangfull. TODO change kError to throw exception
- // ********************************************************************** //
- // ********************************************************************** //
- // ********************************************************************** //
- int SubPopulation::Selection(std::vector<Real> crossover_u, long i) {
- bool is_evaluated = false;
- Real f_current = 0.0;
- for (auto f : evaluated_fitness_for_current_vectors_) {
- if (f.second == i) {
- f_current = f.first;
- is_evaluated = true;
- }
- } // end of searching of pre-evaluated fitness for current individual
- if (!is_evaluated) error_status_ = kError;
- Real f_best = evaluated_fitness_for_current_vectors_.front().first;
- Real f_crossover_u = FitnessFunction(crossover_u);
- bool is_success = f_crossover_u > f_current
- || f_crossover_u == f_best; //Selected for maxima search
- if (is_find_minimum_) is_success = !is_success;
- if (!is_success) {
- // Case of current x and f were new for current generation.
- x_vectors_next_generation_[i] = x_vectors_current_[i];
- for (auto &f : evaluated_fitness_for_next_generation_) {
- if (f.second == i) f.first = f_current;
- } // end of saving old fitness value in new generation.
- } else { // if is_success == true
- x_vectors_next_generation_[i] = crossover_u;
- for (auto &f : evaluated_fitness_for_next_generation_)
- if (f.second == i) f.first = f_crossover_u;
- to_be_archived_best_A_.push_back(x_vectors_current_[i]);
- successful_mutation_parameters_S_F_.push_back(mutation_F_[i]);
- successful_crossover_parameters_S_CR_.push_back(crossover_CR_[i]);
- // if (process_rank_ == kOutput)
- // printf("n%li f_new=%4.2f\n",i,f_crossover_u);
- //PrintSingleVector(crossover_u);
- } // end of dealing with success crossover
- return kDone;
- } // end of int SubPopulation::Selection(std::vector<Real> crossover_u);
- int SubPopulation::Selection(std::vector<Real> crossover_u, void* param, long i) {
- bool is_evaluated = false;
- Real f_current = 0.0;
- for (auto f : evaluated_fitness_for_current_vectors_) {
- if (f.second == i) {
- f_current = f.first;
- is_evaluated = true;
- }
- } // end of searching of pre-evaluated fitness for current individual
- if (!is_evaluated) error_status_ = kError;
- Real f_best = evaluated_fitness_for_current_vectors_.front().first;
- Real f_crossover_u = FitnessFunction_p(crossover_u, param);
- bool is_success = f_crossover_u > f_current
- || f_crossover_u == f_best; //Selected for maxima search
- if (is_find_minimum_) is_success = !is_success;
- if (!is_success) {
- // Case of current x and f were new for current generation.
- x_vectors_next_generation_[i] = x_vectors_current_[i];
- for (auto &f : evaluated_fitness_for_next_generation_) {
- if (f.second == i) f.first = f_current;
- } // end of saving old fitness value in new generation.
- } else { // if is_success == true
- x_vectors_next_generation_[i] = crossover_u;
- for (auto &f : evaluated_fitness_for_next_generation_)
- if (f.second == i) f.first = f_crossover_u;
- to_be_archived_best_A_.push_back(x_vectors_current_[i]);
- successful_mutation_parameters_S_F_.push_back(mutation_F_[i]);
- successful_crossover_parameters_S_CR_.push_back(crossover_CR_[i]);
- // if (process_rank_ == kOutput)
- // printf("n%li f_new=%4.2f\n",i,f_crossover_u);
- //PrintSingleVector(crossover_u);
- } // end of dealing with success crossover
- return kDone;
- } // end of int SubPopulation::Selection(std::vector<Real> crossover_u);
-
- // ********************************************************************** //
- // ********************************************************************** //
- // ********************************************************************** //
- int SubPopulation::ArchiveCleanUp() {
- auto archived_last=archived_best_A_.end();
- archived_best_A_.splice(archived_last, to_be_archived_best_A_);
- auto size_A = archived_best_A_.size();
- long initial_diff = size_A - subpopulation_;
- // if (process_rank_ == kOutput)
- // printf("diff = %li size_A=%li subpop=%li \n ", initial_diff, size_A, subpopulation_);
- // if (initial_diff < 1) return kDone;
- // if (process_rank_ == kOutput)
- // printf("diff = %li size_A=%li \n ", initial_diff, size_A);
- for (long i = 0; i < initial_diff; ++i) {
- long index_to_remove = randint(0, size_A - 1);
- auto element_A = archived_best_A_.begin();
- std::advance(element_A, index_to_remove);
- archived_best_A_.erase(element_A);
- --size_A;
- }
- const unsigned long new_size_A = archived_best_A_.size();
- if (new_size_A > subpopulation_) error_status_ = kError; //TODO change kError to throw exception
- return kDone;
- } // end of int SubPopulation:: ArchiveCleanUp();
- // ********************************************************************** //
- // ********************************************************************** //
- // ********************************************************************** //
- int SubPopulation::Adaption() {
- long elements = 0;
- Real sum = 0.0;
- for (auto CR : successful_crossover_parameters_S_CR_) {
- sum += CR;
- ++elements;
- } // end of collecting data for mean CR
- if (elements == 0) return kDone;
- // Should never be reached for symmetric filling of S_CR and S_F.
- if (successful_mutation_parameters_S_F_.size() == 0) return kDone;
- Real mean_a_CR = sum / static_cast<Real>(elements);
- // Original JADE adaption of mu_CR.
- if (!isPMCRADE_) {
- adaptor_crossover_mu_CR_ =
- (1 - adaptation_frequency_c_) * adaptor_crossover_mu_CR_
- + adaptation_frequency_c_ * mean_a_CR;
- } else {
- // PMCRADE patch for mu_CR
- Real std_S_CR = 0;
- for (auto CR : successful_crossover_parameters_S_CR_)
- std_S_CR += pow2(CR - mean_a_CR);
- std_S_CR = sqrt(std_S_CR / static_cast<Real>(elements));
- const Real PMCRADE_const = 0.07;
- if (std_S_CR < PMCRADE_const) {
- adaptor_crossover_mu_CR_ =
- (1 - adaptation_frequency_c_) * adaptor_crossover_mu_CR_
- + adaptation_frequency_c_ * mean_a_CR;
- } else {
- Real mean_pow2_CR = 0.0;
- for (auto CR : successful_crossover_parameters_S_CR_)
- mean_pow2_CR += pow2(CR);
- mean_pow2_CR = sqrt(mean_pow2_CR/static_cast<Real>(elements));
- adaptor_crossover_mu_CR_ =
- (1 - adaptation_frequency_c_) * adaptor_crossover_mu_CR_
- + adaptation_frequency_c_ * mean_pow2_CR;
- }
- // end of PMCRADE patch
- } // end of if isPMCRADE_
- Real sum_F = 0.0, sum_F2 = 0.0;
- for (auto F : successful_mutation_parameters_S_F_) {
- sum_F += F;
- sum_F2 += F*F;
- } // end of collection data for Lehmer mean F
- Real mean_l_F = sum_F2 / sum_F;
- adaptor_mutation_mu_F_ =
- (1 - adaptation_frequency_c_) * adaptor_mutation_mu_F_
- + adaptation_frequency_c_ * mean_l_F;
- return kDone;
- } // end of int SubPopulation::Adaption();
- // ********************************************************************** //
- // ********************************************************************** //
- // ********************************************************************** //
- int SubPopulation::RunOptimization() {
- //if (process_rank_ == kOutput) printf("Start optimization..\n");
- if (error_status_) return error_status_;
- adaptor_mutation_mu_F_ = 0.5;
- adaptor_crossover_mu_CR_ = 0.5;
- archived_best_A_.clear();
- CreateInitialPopulation();
- x_vectors_next_generation_ = x_vectors_current_;
- EvaluateCurrentVectors();
- evaluated_fitness_for_next_generation_ =
- evaluated_fitness_for_current_vectors_;
- for (long g = 0; g < total_generations_max_; ++g) {
- if (process_rank_ == kOutput && g%100 == 0) printf("%li\n",g);
- to_be_archived_best_A_.clear();
- successful_mutation_parameters_S_F_.clear();
- successful_crossover_parameters_S_CR_.clear();
- // //debug section
- // if (process_rank_ == kOutput)
- // printf("============== Generation %li =============\n", g);
- PrintPopulation();
- //PrintEvaluated();
- std::cin.get();
- //end of debug section
- for (unsigned long i = 0; i < subpopulation_; ++i) {
- SetCRiFi(i);
- std::vector<Real> mutated_v, crossover_u;
- mutated_v = Mutation(i);
- crossover_u = Crossover(mutated_v, i);
- Selection(crossover_u, i);
- } // end of for all individuals in subpopulation
- ArchiveCleanUp();
- Adaption();
- x_vectors_current_.swap(x_vectors_next_generation_);
- evaluated_fitness_for_current_vectors_
- .swap(evaluated_fitness_for_next_generation_);
- SortEvaluatedCurrent();
- if (error_status_) return error_status_;
- } // end of stepping generations
- PrintPopulation();
- PrintEvaluated();
- return kDone;
- } // end of int SubPopulation::RunOptimization()
- int SubPopulation::RunOptimization(std::ostream &out, void* param) {
- //if (process_rank_ == kOutput) printf("Start optimization..\n");
- if (error_status_) return error_status_;
- adaptor_mutation_mu_F_ = 0.5;
- adaptor_crossover_mu_CR_ = 0.5;
- archived_best_A_.clear();
- CreateInitialPopulation();
- x_vectors_next_generation_ = x_vectors_current_;
- EvaluateCurrentVectors(param);
- evaluated_fitness_for_next_generation_ = evaluated_fitness_for_current_vectors_;
- for (long g = 0; g < total_generations_max_; ++g) {
- if (process_rank_ == kOutput && g%100 == 0) printf("%li\n",g);
- to_be_archived_best_A_.clear();
- successful_mutation_parameters_S_F_.clear();
- successful_crossover_parameters_S_CR_.clear();
- PrintPopulation(g, out);
- for (unsigned long i = 0; i < subpopulation_; ++i) {
- SetCRiFi(i);
- std::vector<Real> mutated_v, crossover_u;
- mutated_v = Mutation(i);
- crossover_u = Crossover(mutated_v, i);
- Selection(crossover_u, param, i);
- } // end of for all individuals in subpopulation
- ArchiveCleanUp();
- Adaption();
- x_vectors_current_.swap(x_vectors_next_generation_);
- evaluated_fitness_for_current_vectors_
- .swap(evaluated_fitness_for_next_generation_);
- SortEvaluatedCurrent();
- if (error_status_) return error_status_;
- } // end of stepping generations
- PrintPopulation();
- PrintEvaluated();
- return kDone;
- } // end of int SubPopulation::RunOptimization()
- // ********************************************************************** //
- // ********************************************************************** //
- // ********************************************************************** //
- std::vector<Real> SubPopulation::Crossover(std::vector<Real> mutation_v, long i) {
- const Real CR_i = crossover_CR_[i];
- std::vector<Real> crossover_u, x_current;
- crossover_u.resize(dimension_);
- x_current = x_vectors_current_.at(i);
- unsigned long j_rand = randint(0, dimension_ - 1);
- for (unsigned long c = 0; c < dimension_; ++c) {
- if (c == j_rand || rand(0,1) < CR_i)
- crossover_u[c] = mutation_v[c];
- else
- crossover_u[c] = x_current[c];
- }
- // //debug section
- // if (process_rank_ == kOutput)
- // printf("x -> v -> u with CR_i=%4.2f j_rand=%li\n", CR_i, j_rand);
- // PrintSingleVector(mutation_v);
- // PrintSingleVector(x_current);
- // PrintSingleVector(crossover_u);
- // //end of debug section
- return crossover_u;
- } // end of std::vector<Real> SubPopulation::Crossover();
- // ********************************************************************** //
- // ********************************************************************** //
- // ********************************************************************** //
- std::vector<Real> SubPopulation::Mutation(long i) {
- std::vector<Real> mutation_v, x_best_current, x_random_current,
- x_random_archive_and_current, x_current;
- x_current = x_vectors_current_.at(i);
- x_best_current = GetXpBestCurrent();
- // //debug
- // if (process_rank_ == kOutput) printf("x_best: ");
- // PrintSingleVector(x_best_current);
- long index_of_random_current = -1;
- x_random_current = GetXRandomCurrent(&index_of_random_current, i);
- // //debug
- // if (process_rank_ == kOutput) printf("x_random: ");
- // PrintSingleVector(x_random_current);
- x_random_archive_and_current = GetXRandomArchiveAndCurrent(index_of_random_current, i);
- // //debug
- // if (process_rank_ == kOutput) printf("x_random with archive: ");
- // PrintSingleVector(x_random_archive_and_current);
- mutation_v.resize(dimension_);
- Real F_i = mutation_F_[i];
- for (unsigned long c = 0; c < dimension_; ++c) {
- // Mutation
- mutation_v[c] = x_current[c]
- + F_i * (x_best_current[c] - x_current[c])
- + F_i * (x_random_current[c]
- - x_random_archive_and_current[c]);
- // Bounds control
- if (mutation_v[c] > x_ubound_[c])
- mutation_v[c] = (x_ubound_[c] + x_current[c])/2;
- if (mutation_v[c] < x_lbound_[c])
- mutation_v[c] = (x_lbound_[c] + x_current[c])/2;
- }
- // //debug section
- // int isSame = 888, isSame2 = 7777, isSame3 =11111;
- // for (long c = 0; c < dimension_; ++c) {
- // Real norm = std::abs(mutation_v[c] - x_current[c]);
- // Real norm2 = std::abs(x_random_current[c] - x_current[c]);
- // Real norm3 = std::abs(x_random_current[c]
- // - x_random_archive_and_current[c]);
- // if ( norm > 0.0001) isSame = 0;
- // if ( norm2 > 0.0001) isSame2 = 0;
- // if ( norm3 > 0.0001) isSame3 = 0;
- // }
- // if (process_rank_ == kOutput) printf("mutation_v%i%i%i: ",isSame, isSame2, isSame3);
- // PrintSingleVector(mutation_v);
- // if (process_rank_ == kOutput) printf("current _v%i%i%i: ",isSame, isSame2, isSame3);
- // PrintSingleVector(x_current);
- // if (process_rank_ == kOutput)
- // printf(" -> f = %4.2f F_i=%4.2f\n",
- // FitnessFunction(mutation_v), F_i);
- // //end of debug section
- return mutation_v;
- } // end of std::vector<Real> SubPopulation::Mutation();
- // ********************************************************************** //
- // ********************************************************************** //
- // ********************************************************************** //
- std::vector<Real> SubPopulation::GetXpBestCurrent() {
- const unsigned long n_best_total = static_cast<long>
- (floor(subpopulation_ * best_share_p_ ));
- if (n_best_total == subpopulation_) error_status_ = kError; //TODO change kError to throw exception
- long best_n = randint(0, n_best_total);
- long best_n_index = -1, i = 0;
- for (auto x : evaluated_fitness_for_current_vectors_) {
- if (i == best_n) {
- best_n_index = x.second;
- break;
- }
- ++i;
- }
- return x_vectors_current_.at(best_n_index);
- } // end of std::vector<Real> SubPopulation::GetXpBestCurrent();
- // ********************************************************************** //
- // ********************************************************************** //
- // ********************************************************************** //
- std::vector<Real> SubPopulation::GetXRandomCurrent(long *index, long forbidden_index) {
- long random_n = randint(0, subpopulation_-1);
- while (random_n == forbidden_index) random_n = randint(0, subpopulation_-1);
- (*index) = random_n;
- return x_vectors_current_.at(random_n);
- } // end of std::vector<Real> SubPopulation::GetXRandomCurrent()
- // ********************************************************************** //
- // ********************************************************************** //
- // ********************************************************************** //
- std::vector<Real> SubPopulation::GetXRandomArchiveAndCurrent
- (unsigned long forbidden_index1, unsigned long forbidden_index2) {
- long archive_size = archived_best_A_.size();
- unsigned long random_n = randint(0, subpopulation_ + archive_size - 1);
- while (random_n == forbidden_index1 || random_n == forbidden_index2)
- random_n = randint(0, subpopulation_ + archive_size - 1);
- if (random_n < subpopulation_) return x_vectors_current_.at(random_n);
- random_n -= subpopulation_;
- unsigned long i = 0;
- for (auto x : archived_best_A_) {
- if (i == random_n) {
- // //debug
- // if (process_rank_ == kOutput) printf("Using Archive!!\n");
- return x;
- }
- ++i;
- } // end of selecting from archive
- error_status_ = kError; //TODO change kError to throw exception
- std::vector<Real> x;
- return x;
- } // end of std::vector<Real> SubPopulation::GetXRandomArchiveAndCurrent()
- // ********************************************************************** //
- // ********************************************************************** //
- // ********************************************************************** //
- int SubPopulation::SetCRiFi(long i) {
- long k = 0;
- while (1) {
- mutation_F_[i] = randc(adaptor_mutation_mu_F_, 0.1);
- if (mutation_F_[i] > 1) {
- mutation_F_[i] = 1;
- break;
- }
- if (mutation_F_[i] > 0) break;
- ++k;
- if (k > 10) {
- mutation_F_[i] = 0.001;
- break;
- }
- if (k > 100) printf("k");
- }
- crossover_CR_[i] = randn(adaptor_crossover_mu_CR_,0.1);
- if (crossover_CR_[i] > 1) crossover_CR_[i] = 1;
- if (crossover_CR_[i] < 0) crossover_CR_[i] = 0;
- return kDone;
- } // end of int SubPopulation::SetCRiFi(long i)
- // ********************************************************************** //
- // ********************************************************************** //
- // ********************************************************************** //
- /// %todo Change returned kError to meangfull error code.
- int SubPopulation::Init(long total_population, long dimension) {// NOLINT
- total_population_ = total_population;
- if (total_population_ < 1)
- throw std::invalid_argument("You should set population > 0!");
- dimension_ = dimension;
- if (dimension_ < 1)
- throw std::invalid_argument("You should set dimension > 0!");
- MPI_Comm_rank(MPI_COMM_WORLD, &process_rank_);
- MPI_Comm_size(MPI_COMM_WORLD, &number_of_processes_);
- if (process_rank_ < 0)
- throw std::invalid_argument("MPI problem: process_rank_ < 0!");
- if (number_of_processes_ < 1)
- throw std::invalid_argument("MPI problem: number_of_processes_ < 1!");
- std::random_device rd;
- generator_.seed(rd());
- // //debug
- // CheckRandom();
- subpopulation_ = total_population;
- current_generation_ = 0;
- x_vectors_current_.resize(subpopulation_);
- for (auto &x : x_vectors_current_) x.resize(dimension_);
- x_vectors_next_generation_.resize(subpopulation_);
- for (auto &x : x_vectors_next_generation_) x.resize(dimension_);
- evaluated_fitness_for_current_vectors_.resize(subpopulation_);
- // //debug
- // if (process_rank_ == kOutput) printf("%i, x1 size = %li \n", process_rank_, x_vectors_current_.size());
- x_lbound_.resize(dimension_);
- x_ubound_.resize(dimension_);
- mutation_F_.resize(subpopulation_);
- crossover_CR_.resize(subpopulation_);
- return kDone;
- } // end of void SubPopulation::Init()
- // ********************************************************************** //
- // ********************************************************************** //
- // ********************************************************************** //
- int SubPopulation::PrintPopulation() {
- if (process_rank_ == kOutput) {
- printf("\n");
- for (auto x : evaluated_fitness_for_current_vectors_) {
- long n = x.second;
- Real fitness = x.first;
- printf("%6.2f:% 3li||", fitness, n);
- for (unsigned long c = 0; c < dimension_; ++c)
- printf(" %+7.2f ", x_vectors_current_[n][c]);
- printf("\n");
- }
- // for (long i = 0; i < subpopulation_; ++i) {
- // printf("n%li:", i);
- // for (long c = 0; c < dimension_; ++c) {
- // printf(" %5.2f ", x_vectors_current_[i][c]);
- // }
- // printf("\n");
- // } // end of for each individual
- } // end of if output
- return kDone;
- } // end of int SubPupulation::PrintPopulation()
- int SubPopulation::PrintPopulation(long niter, std::ostream &out) {
- if (process_rank_ == kOutput) {
- //printf("\n");
- auto p = evaluated_fitness_for_current_vectors_.begin();
- out << niter << " " << (*p).first;
- for (unsigned long c = 0; c < dimension_; ++c) out << " " << x_vectors_current_[(*p).second][c];
- out << std::endl;
- } // end of if output
- return kDone;
- } // end of int SubPupulation::PrintPopulation()
-
- // ********************************************************************** //
- // ********************************************************************** //
- // ********************************************************************** //
- int SubPopulation::PrintEvaluated() {
- if (process_rank_ == kOutput) {
- for (auto x : evaluated_fitness_for_current_vectors_)
- printf("%li:%4.2f ", x.second, x.first);
- printf("\n");
- } // end of if output
- return kDone;
- } // end of int SubPopulation::PrintEvaluated()
- // ********************************************************************** //
- // ********************************************************************** //
- // ********************************************************************** //
- int SubPopulation::PrintSingleVector(std::vector<Real> x) {
- if (process_rank_ == kOutput) {
- for (auto c : x) printf("%5.2f ", c);
- printf("\n");
- } // end of output
- return kDone;
- } // end of int SubPopulation::PrintSingleVector(std::vector<Real> x)
- // ********************************************************************** //
- // ********************************************************************** //
- // ********************************************************************** //
- void SubPopulation::SetFeed(std::vector<std::vector<Real> > x_feed_vectors) {
- isFeed_ = true;
- if (dimension_ < 1)
- throw std::invalid_argument("You should set dimension before feed!");
- for (auto x : x_feed_vectors)
- if (x.size() != dimension_)
- throw std::invalid_argument
- ("Feed and optimization dimenstion should be the same size!");
- x_feed_vectors_.clear();
- for (auto &x : x_feed_vectors)
- x_feed_vectors_.push_back(x);
- } // end of void SubPopulation::SetFeed()
- // ********************************************************************** //
- // ********************************************************************** //
- // ********************************************************************** //
- int SubPopulation::CreateInitialPopulation() {
- if ((subpopulation_ - x_feed_vectors_.size()) <1)
- throw std::invalid_argument("Too large feed!");
- x_vectors_current_.resize(subpopulation_ - x_feed_vectors_.size());
- for (auto &x : x_vectors_current_)
- for (unsigned long i = 0; i < dimension_; ++i) {
- if (x_lbound_[i] > x_ubound_[i])
- throw std::invalid_argument("Wrong order of bounds!");
- x[i] = rand(x_lbound_[i], x_ubound_[i]); // NOLINT
- } // end of for each dimension
- // //debug
- // for (auto x : x_vectors_current_[0]) if (process_rank_ == kOutput) printf("%g ",x);
- for (auto x: x_feed_vectors_) {
- x_vectors_current_.push_back(x);
- if (process_rank_ == kOutput) {
- printf("--=-- Feed:\n");
- for (auto index:x) printf(" %+7.2f", index);
- printf("\n");
- }
- }
- if (x_vectors_current_.size() != subpopulation_)
- throw std::invalid_argument("Population is not full after feed!");
- x_feed_vectors_.clear();
- // if (process_rank_ == kOutput) {
- // printf("==--== Initial population:\n");
- // EvaluateCurrentVectors();
- // PrintPopulation();
- // }
- return kDone;
- } // end of int SubPopulation::CreateInitialPopulation()
- // ********************************************************************** //
- // ********************************************************************** //
- // ********************************************************************** //
- int SubPopulation::SortEvaluatedCurrent() {
- evaluated_fitness_for_current_vectors_
- .sort([=](const std::pair<Real, long>& a, // NOLINT
- const std::pair<Real, long>& b) { // NOLINT
- bool cmp = a.first < b.first;
- if (is_find_minimum_) return cmp;
- return !cmp;
- });
- return kDone;
- } // end of int SubPopulation::SortEvaluatedCurrent()
- // ********************************************************************** //
- // ********************************************************************** //
- // ********************************************************************** //
- int SubPopulation::EvaluateCurrentVectors() {
- evaluated_fitness_for_current_vectors_.clear();
- for (unsigned long i = 0; i < subpopulation_; ++i) { // NOLINT
- auto tmp = std::make_pair(FitnessFunction(x_vectors_current_[i]), i);
- evaluated_fitness_for_current_vectors_.push_back(tmp);
- }
- SortEvaluatedCurrent();
- // //debug
- // if (process_rank_ == kOutput) printf("\n After ");
- // for (auto val : evaluated_fitness_for_current_vectors_)
- // if (process_rank_ == kOutput) printf("%g ", val.first);
- return kDone;
- } // end of int SubPopulation::EvaluateCurrentVectors()
-
- int SubPopulation::EvaluateCurrentVectors(void* param) {
- evaluated_fitness_for_current_vectors_.clear();
- for (unsigned long i = 0; i < subpopulation_; ++i) { // NOLINT
- auto tmp = std::make_pair(FitnessFunction_p(x_vectors_current_[i], param), i);
- evaluated_fitness_for_current_vectors_.push_back(tmp);
- }
- SortEvaluatedCurrent();
- // //debug
- // if (process_rank_ == kOutput) printf("\n After ");
- // for (auto val : evaluated_fitness_for_current_vectors_)
- // if (process_rank_ == kOutput) printf("%g ", val.first);
- return kDone;
- } // end of int SubPopulation::EvaluateCurrentVectors()
- // ********************************************************************** //
- // ********************************************************************** //
- // ********************************************************************** //
- void SubPopulation::SetAllBoundsVectors
- (std::vector<Real> lbound, std::vector<Real> ubound) {
- x_lbound_.clear();
- x_ubound_.clear();
- for (auto x : lbound) x_lbound_.push_back(x);
- for (auto x : ubound) x_ubound_.push_back(x);
- }
- // ********************************************************************** //
- // ********************************************************************** //
- // ********************************************************************** //
- int SubPopulation::SetAllBounds(Real lbound, Real ubound) {
- if (lbound >= ubound) {
- error_status_ = kError;
- return kError; //TODO change kError to throw exception
- }
- for (auto &x : x_lbound_) x = lbound;
- for (auto &x : x_ubound_) x = ubound;
- return kDone;
- } // end of int SubPopulation::SetAllBounds(Real lbound, Real ubound)
- // ********************************************************************** //
- // ********************************************************************** //
- // ********************************************************************** //
- Real SubPopulation::randn(Real mean, Real stddev) {
- std::normal_distribution<Real> distribution(mean, stddev);
- return distribution(generator_);
- } // end of Real SubPopulation::randn(Real mean, Real stddev)
- // ********************************************************************** //
- // ********************************************************************** //
- // ********************************************************************** //
- Real SubPopulation::randc(Real location, Real scale) {
- std::cauchy_distribution<Real> distribution(location, scale);
- return distribution(generator_);
- } // end of Real SubPopulation::randc(Real location, Real scale)
- // ********************************************************************** //
- // ********************************************************************** //
- // ********************************************************************** //
- long SubPopulation::randint(long lbound, long ubound) { // NOLINT
- std::uniform_int_distribution<long> distribution(lbound, ubound); // NOLINT
- return distribution(generator_);
- }
- // ********************************************************************** //
- // ********************************************************************** //
- // ********************************************************************** //
- Real SubPopulation::rand(Real lbound, Real ubound) { // NOLINT
- std::uniform_real_distribution<Real> distribution(lbound, ubound);
- return distribution(generator_);
- } // end of Real rand(Real lbound, Real ubound)
- // ********************************************************************** //
- // ********************************************************************** //
- // ********************************************************************** //
- void SubPopulation::CheckRandom() {
- std::map<int, int> hist_n, hist_c, hist_int, hist;
- int factor = 1000;
- for (int n = 0; n < 100*factor; ++n) {
- ++hist_n[std::round(randn(0, 2))];
- ++hist_c[std::round(randc(0, 2))];
- ++hist_int[std::round(randint(0, 10))];
- ++hist[std::round(rand(0, 15))]; // NOLINT
- }
- if (process_rank_ == kOutput) {
- printf("Normal (0,2)\n");
- for (auto p : hist_n) {
- if (p.second > factor)
- printf("%i: % 4i %s\n", process_rank_, p.first,
- std::string(p.second/factor, '*').c_str());
- } // end of for p in hist_n
- printf("Cauchy (0,2)\n");
- for (auto p : hist_c) {
- if (p.second > factor)
- printf("%i: % 4i %s\n", process_rank_, p.first,
- std::string(p.second/factor, '*').c_str());
- } // end of for p in hist_c
- printf("Uniform int (0,10)\n");
- for (auto p : hist_int) {
- if (p.second > factor)
- printf("%i: % 4i %s\n", process_rank_, p.first,
- std::string(p.second/factor, '*').c_str());
- } // end of for p in hist_int
- printf("Uniform Real (0,15)\n");
- for (auto p : hist) {
- if (p.second > factor)
- printf("%i: % 4i %s\n", process_rank_, p.first,
- std::string(p.second/factor, '*').c_str());
- } // end of for p in hist
- } // end of if current process_rank_ == kOutput
- }
- // ********************************************************************** //
- // ********************************************************************** //
- // ********************************************************************** //
- int SubPopulation::SetBestShareP(Real p) {
- if (p < 0 || p > 1) {
- error_status_ = kError;
- return kError; //TODO change kError to throw exception
- }
- best_share_p_ = p;
- return kDone;
- } // end of int SubPopulation::SetBestShareP(Real p)
- // ********************************************************************** //
- // ********************************************************************** //
- // ********************************************************************** //
- int SubPopulation::SetAdapitonFrequencyC(Real c) {
- if (c < 0 || c > 1) {
- error_status_ = kError;
- return kError; //TODO change kError to throw exception
- }
- adaptation_frequency_c_ = c;
- return kDone;
- } // end of int SubPopulation::SetAdapitonFrequency(Real c)
- // ********************************************************************** //
- // ********************************************************************** //
- // ********************************************************************** //
- int SubPopulation::SetDistributionLevel(int level) {
- distribution_level_ = level;
- return kDone;
- }
- // end of int SubPopulation::SetDistributionLevel(int level)
- // ********************************************************************** //
- // ********************************************************************** //
- // ********************************************************************** //
- int SubPopulation::PrintParameters(std::string comment) {
- if (process_rank_ == 0) {
- printf("#%s dim=%li NP=%li(of %li) p=%4.2f c=%4.2f generation=%li\n",
- comment.c_str(),dimension_, subpopulation_, total_population_,
- best_share_p_, adaptation_frequency_c_, total_generations_max_
- );
- fflush(stdout);
- } // end of output
- return kDone;
- } // end of int SubPopulation::PrintParameters(std::string comment)
- // ********************************************************************** //
- // ********************************************************************** //
- // ********************************************************************** //
- int SubPopulation::PrintResult(std::string comment) {
- if (distribution_level_ == 0) {
- auto x = evaluated_fitness_for_current_vectors_.front();
- std::vector<Real> to_send {x.first};
- //printf("%8.5g\n ", x.first);
- AllGatherVectorDouble(to_send);
- if (process_rank_ == 0) {
- Real sum = 0;
- Real size = static_cast<Real>(recieve_Real_.size());
- for (auto x : recieve_Real_) sum += x;
- Real mean = sum/size;
- Real sigma = 0;
- for (auto x : recieve_Real_) sigma += pow2(x - mean);
- sigma = sqrt(sigma/size);
- printf("%s gen%li, mean %4.1e (stddev %4.1e = %3.2g %%) runs(%g)\n",
- comment.c_str(), total_generations_max_, mean,sigma,
- sigma*100.0/mean,size);
- // for (auto x : recieve_Real_)
- // printf("%18.15g\n", x);
- }
- }
- return kDone;
- } // end of int SubPopulation::PrintResult()
- // ********************************************************************** //
- // ********************************************************************** //
- // ********************************************************************** //
- std::vector<Real> SubPopulation::GetFinalFitness() {
- recieve_Real_.clear();
- if (distribution_level_ == 0) {
- auto x = evaluated_fitness_for_current_vectors_.front();
- std::vector<Real> to_send {x.first};
- AllGatherVectorDouble(to_send);
- }
- return recieve_Real_;
- } // end of sdt::vector<Real> SubPopulation::GetFinalFitness();
- // ********************************************************************** //
- // ********************************************************************** //
- // ********************************************************************** //
- std::vector<Real> SubPopulation::GetBest(Real *best_fitness) {
- auto x = evaluated_fitness_for_current_vectors_.front();
- (*best_fitness) = x.first;
- return x_vectors_current_[x.second];
- } // end of std::vector<Real> SubPopulation::GetBest(Real *best_fitness)
- // ********************************************************************** //
- // ********************************************************************** //
- // ********************************************************************** //
- std::vector<Real> SubPopulation::GetWorst(Real *worst_fitness) {
- auto x = evaluated_fitness_for_current_vectors_.back();
- (*worst_fitness) = x.first;
- return x_vectors_current_[x.second];
- } // end of std::vector<Real> SubPopulation::GetWorst(Real *worst_fitness)
- // ********************************************************************** //
- // ********************************************************************** //
- // ********************************************************************** //
- int SubPopulation::AllGatherVectorDouble(std::vector<Real> to_send) {
- long size_single = to_send.size();
- long size_all = size_single * number_of_processes_;
- recieve_Real_.clear();
- recieve_Real_.resize(size_all);
- MPI_Allgather(&to_send.front(), size_single, MPI_DOUBLE,
- &recieve_Real_.front(), size_single, MPI_DOUBLE,
- MPI_COMM_WORLD);
- return kDone;
- } // end of int SubPopulation::AllGatherVectorDouble(std::vector<Real> to_send);
- // ********************************************************************** //
- // ********************************************************************** //
- // ********************************************************************** //
- int SubPopulation::AllGatherVectorLong(std::vector<long> to_send) {
- long size_single = to_send.size();
- long size_all = size_single * number_of_processes_;
- recieve_long_.clear();
- recieve_long_.resize(size_all);
- MPI_Allgather(&to_send.front(), size_single, MPI_LONG,
- &recieve_long_.front(), size_single, MPI_LONG,
- MPI_COMM_WORLD);
- return kDone;
- } // end of int SubPopulation::AllGatherVectorLong(std::vector<long> to_send);
- // ********************************************************************** //
- // ********************************************************************** //
- // ********************************************************************** //
- } // end of namespace jade
|