See More

// // main.cpp // ConfigurableGA // // Created by Furong Ye on 26/10/2020. // Copyright © 2020 Furong Ye. All rights reserved. // #include "modularGA.hpp" #include "ioh.hpp" #include using namespace std; /// \fn std::string strstrip(std::string s) /// \brief To erase blanks in the front and end of a string. /// /// \para s string /// \return string static std::string strstrip(std::string s) { if (s.empty()) { return s; } s.erase(0,s.find_first_not_of(' ')); /// For string line end with '\r' in windows systems. s.erase(s.find_last_not_of('\r') + 1); s.erase(s.find_last_not_of(' ') + 1); return s; } /// \fn std::vector get_int_vector_parse_string(std::string input, const int _min, const int _max) { /// \brief To get a vector of integer values with a range 'n-m' /// /// Return a vector of integer value. The supported formats are: /// '-m', [_min, m] /// 'n-', [n, _max] /// 'n-m', [n, m] /// 'n-x-y-z-m', [n,m] /// \para input string /// \para _int int /// \para _max int /// \return std::vector static std::vector get_int_vector_parse_string(std::string input, const int _min, const int _max) { std::vector<:string> spiltstring; std::string tmp; int tmpvalue,tmpvalue1; std::vector result; size_t n = input.size(); input = strstrip(input); for (size_t i = 0; i < n; ++i) { if (input[i] != ',' && input[i] != '-' && !isdigit(input[i])) { cerr << "The configuration consists invalid characters."; } } std::stringstream raw(input); while(getline(raw, tmp, ',')) spiltstring.push_back(tmp); n = spiltstring.size(); for (size_t i = 0; i < n; ++i) { //size_t l = spiltstring[i].size(); if (spiltstring[i][0] == '-') { /// The condition beginning with "-m" if(i != 0) { cerr << "Format error in configuration."; } else { tmp = spiltstring[i].substr(1); if (tmp.find('-') != std::string::npos) { cerr << "Format error in configuration."; } tmpvalue = std::stoi(tmp); if (tmpvalue < _min) { cerr << "Input value exceeds lowerbound."; } for (int value = _min; value <= tmpvalue; ++value) { result.push_back(value); } } } else if(spiltstring[i][spiltstring[i].length()-1] == '-') { /// The condition endding with "n-" if (i != spiltstring.size() - 1) { cerr << "Format error in configuration."; } else { tmp = spiltstring[i].substr(0,spiltstring[i].length() - 1); if (tmp.find('-') != std::string::npos) { cerr << "Format error in configuration."; } tmpvalue = std::stoi(tmp); if (tmpvalue > _max) { cerr << "Input value exceeds upperbound."; } for (int value = _max; value <= tmpvalue; --value) { result.push_back(value); } } } else { /// The condition with "n-m,n-x-m" std::stringstream tempraw(spiltstring[i]); std::vector<:string> tmpvaluevector; while (getline(tempraw, tmp, '-')) { tmpvaluevector.push_back(tmp); } tmpvalue = std::stoi(tmpvaluevector[0]); tmpvalue1 = std::stoi(tmpvaluevector[tmpvaluevector.size()-1]); if (tmpvalue > tmpvalue1) { cerr << "Format error in configuration."; } if (tmpvalue < _min) { cerr << "Input value exceeds lowerbound."; } if (tmpvalue1 > _max) { cerr << "Input value exceeds upperbound."; } for(int value = tmpvalue; value <= tmpvalue1; ++value) result.push_back(value); } } return result; } /** * Alrogrithm names: * ea : (1+1)-EA>0 p = 1/n * ea2 : (1+1)-EA>0 p = 2/n * ea23 : (1+1)-EA>0 p = 2/3n * llea : (1+(lambda,lambda))-EA>_0, initial lambda = 10, p = 1/n * rls : randomized local search * rs : random search * ghc : greedy hill climber * fga : (1+1)-fast GA * 2ratega : (1+10)-EA>0 with 2rate self adaptation of mutation rate * umda : univarate marginal distribution algorithm, population size = 50 * sa : simulated annealing * sars : the simulated annealing algorithm with exponential temperature schedule with iterative restarts * fea : (1+1)-EA>0 with frequency fitness assignment */ void runAlgorithm(shared_ptr<:suite::suite>> suite, const string algorithm_name, const string dir, const int budget, const int runs, const unsigned seed) { if (algorithm_name == "ea") { modularGA::ga::staticEA ea(1, 1, 1.0); ea.run(dir, algorithm_name, suite, budget, std::numeric_limits::max(), runs, seed); } else if (algorithm_name == "ea2") { modularGA::ga::staticEA ea(1, 1, 2.0); ea.run(dir, algorithm_name, suite, budget, std::numeric_limits::max(), runs, seed); } else if (algorithm_name == "ea23") { modularGA::ga::staticEA ea(1, 1, 1.5); ea.run(dir, algorithm_name, suite, budget, std::numeric_limits::max(), runs, seed); } else if (algorithm_name == "llea") { modularGA::ga::oneLambdaLambdaEA llEA(10); llEA.run(dir, algorithm_name, suite, budget, std::numeric_limits::max(), runs, seed); } else if (algorithm_name == "rls") { modularGA::ga::RLS rls; rls.run(dir, algorithm_name, suite, budget, std::numeric_limits::max(), runs, seed); } else if (algorithm_name == "rs") { modularGA::rs::RandomSearch rs; rs.run(dir, algorithm_name, suite, budget, runs, seed); } else if (algorithm_name == "ghc") { modularGA::ghc::GreedyHillClimber ghc; ghc.run(dir, algorithm_name, suite, budget, runs, seed); } else if (algorithm_name == "fga") { modularGA::ga::FastGA fGA(1, 1); fGA.run(dir, algorithm_name, suite, budget, std::numeric_limits::max(), runs, seed); } else if (algorithm_name == "2ratega") { modularGA::ga::TwoRateEA twoRateGA(10); twoRateGA.run(dir, algorithm_name, suite, budget, std::numeric_limits::max(), runs, seed); } else if (algorithm_name == "umda") { modularGA::eda::EstimationOfDistribution umda(25, 50); umda.run(dir, algorithm_name, suite, budget, std::numeric_limits::max(), runs, seed); } else if (algorithm_name == "normea") { modularGA::ga::NormEA normEA(10); normEA.run(dir, algorithm_name, suite, budget, std::numeric_limits::max(), runs, seed); } else if (algorithm_name == "varea") { modularGA::ga::VarEA varEA(10); varEA.run(dir, algorithm_name, suite, budget, std::numeric_limits::max(), runs, seed); } else if (algorithm_name == "sa") { modularGA::sa::run_simulated_annealing_exp(dir, suite, budget, runs, seed); } else if (algorithm_name == "sars") { modularGA::sars::run_simulated_annealing_exp_rs(dir, suite, budget, runs, seed); // } else if (algorithm_name == "fea") { // run_fea1p1(dir, suite, budget, runs, seed); } else { cout << "Unkownn algorithm : " << algorithm_name << endl; } } /** * Arguments: suite_name problem_id instance_id dimension * algorithm_name : 'name' * suite_name : 'name', name \in {'PBO','WmodelOneMax', 'WmodelLeadingOnes'} * problem_id : 'start-end' , id \in [1..25] for PBO, [1..product.size()] for Wmodel extensions. * instance_id: 'start-end' , id \in [1..100] * dimension : 'dimension1, dimension2, ...' * dir : 'dir', the directory where the output folder locates. * runs : 'number_of_indepedent_runs', runs > 1 * budget : 'budget', the maximum function evaluations. budget > 1 * seed : 'seed', a random seed * * An instance: ./main ea pbo 1-3 1-5 10,100 ./ 10 100 1 **/ int main(int argc, const char *argv[]) { const vector dummy = {0.0, 0.9}; const vector epistasis = {0, 2, 5, 7}; const vector neutrality = {1, 5}; const vector ruggedness = {0, 0.8, 1}; int number_of_w_problems = dummy.size() * epistasis.size() * neutrality.size() * ruggedness.size(); string algorithm_name = argv[1]; string suite_name = argv[2]; string problem_str = argv[3]; string instance_str = argv[4]; string dimension_str = argv[5]; string dir = argv[6]; int runs = stoi(argv[7]); int budget = stoi(argv[8]); unsigned seed = static_cast (stoi(argv[9])); transform(suite_name.begin(),suite_name.end(),suite_name.begin(),::tolower); transform(algorithm_name.begin(),algorithm_name.end(),algorithm_name.begin(),::tolower); auto problems = get_int_vector_parse_string(problem_str,0,25); auto instances = get_int_vector_parse_string(instance_str,0,100); auto dimensions = get_int_vector_parse_string(dimension_str,2,20000); if (suite_name == "pbo") { auto suite = ioh::suite::SuiteRegistry<:problem::integersingleobjective>::instance() .create("PBO", problems , instances, dimensions); runAlgorithm(suite, algorithm_name, dir, budget, runs, seed); } else { cout << "Unknown suite : " << suite_name << ", avaliable options are \"PBO\", \"WModelOneMax\", and \"WModelLeadingOnes\"." << endl; } return 0; }