diff --git a/eo/contrib/irace/CMakeLists.txt b/eo/contrib/irace/CMakeLists.txt new file mode 100644 index 000000000..37c82187e --- /dev/null +++ b/eo/contrib/irace/CMakeLists.txt @@ -0,0 +1,97 @@ + +###################################################################################### +# Project settings +###################################################################################### + +cmake_minimum_required(VERSION 3.10 FATAL_ERROR) + +project("paradiseo-irace") + +enable_language(CXX) # C++ +set(CMAKE_CXX_STANDARD 17) + +## Current version +set(VERSION_MAJOR 0 CACHE STRING "Major version number" ) +set(VERSION_MINOR 1 CACHE STRING "Minor version number" ) +set(VERSION_PATCH 0 CACHE STRING "Patch version number" ) +mark_as_advanced(VERSION_MAJOR VERSION_MINOR VERSION_PATCH) + + +###################################################################################### +# Configurable user settings +###################################################################################### + +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wpedantic") + +# put binaries in the build directory +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) + +# Dump used compiler flags. +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + + +###################################################################################### +# Dependencies +###################################################################################### + +# ParadisEO +set(PARADISEO_ROOT "../../../../paradiseo" CACHE PATH "Where to find ParadisEO") +set(PARADISEO_BUILD "${PARADISEO_ROOT}/build" CACHE PATH "Build dir of ParadisEO") + +include_directories(${PARADISEO_ROOT}) +include_directories(${PARADISEO_ROOT}/eo/src) +link_directories(${PARADISEO_BUILD}/lib) +set(PARADISEO_LIBRARIES ga eoutils eo) + +# IOH +set(IOH_ROOT "~/code/IOHexperimenter/" CACHE PATH "Where to find IOHexperimenter") +find_path(IOH_PROBLEM_H "IOHprofiler_problem.h" PATHS ${IOH_ROOT}/src/Template/) +find_library(IOH_LIBRARY "IOH" PATHS ${IOH_ROOT} PATH_SUFFIXES release Release debug Debug build Build) + +if(EXISTS ${IOH_PROBLEM_H} AND EXISTS ${IOH_LIBRARY}) + message(STATUS "Found IOH in ${IOH_ROOT}") + include_directories(${IOH_ROOT}/build/Cpp/src/) + link_directories(${IOH_ROOT}/build/Cpp/bin/) + + # Workaround IOH's poorly designed headers inclusion scheme. + SET(PROBLEMS_BBOB_DIR "src/Problems/BBOB") + SET(PROBLEMS_BBOB_COMMON_DIR "src/Problems/BBOB/bbob_common_used_functions") + SET(PROBLEMS_COMMON_DIR "src/Problems/common_used_functions") + SET(PROBLEMS_PBO_DIR "src/Problems/PBO") + SET(PROBLEMS_WMODEL_DIR "src/Problems/WModel") + SET(PROBLEMS_PYTHON_DIR "src/Problems/Python") + SET(SUITES_DIR "src/Suites") + SET(TEMPLATE_DIR "src/Template") + SET(TEMPLATE_EXPERIMENTS_DIR "src/Template/Experiments") + SET(TEMPLATE_LOGGERS_DIR "src/Template/Loggers") + SET(IOHEXPERIMENTER_DIR + "${IOH_ROOT}/${PROBLEMS_COMMON_DIR}" + "${IOH_ROOT}/${PROBLEMS_BBOB_DIR}" + "${IOH_ROOT}/${PROBLEMS_BBOB_COMMON_DIR}" + "${IOH_ROOT}/${PROBLEMS_PBO_DIR}" + "${IOH_ROOT}/${PROBLEMS_WMODEL_DIR}" + "${IOH_ROOT}/${PROBLEMS_PYTHON_DIR}" + "${IOH_ROOT}/${SUITES_DIR}" + "${IOH_ROOT}/${TEMPLATE_DIR}" + "${IOH_ROOT}/${TEMPLATE_EXPERIMENTS_DIR}" + "${IOH_ROOT}/${TEMPLATE_LOGGERS_DIR}" + ) + include_directories(${IOHEXPERIMENTER_DIR}) + +else() + if(NOT EXISTS ${IOH_PROBLEM_H}) + message(FATAL_ERROR "Could not find `IOHprofiler_problem.h` in: ${IOH_ROOT}/src/Template/ (did you forget to compile it?)") + endif() + if(NOT EXISTS ${IOH_LIBRARIES}) + message(FATAL_ERROR "Could not find `libIOH` in: ${IOH_ROOT}/[release|debug|build] (did you forget to compile it?)") + endif() +endif() + + +###################################################################################### +# Start building +###################################################################################### + +add_executable(fastga fastga.cpp) +target_link_libraries(fastga ${PARADISEO_LIBRARIES} ${IOH_LIBRARY}) + diff --git a/eo/contrib/irace/fastga.cpp b/eo/contrib/irace/fastga.cpp new file mode 100644 index 000000000..9682af59f --- /dev/null +++ b/eo/contrib/irace/fastga.cpp @@ -0,0 +1,195 @@ +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +// using Particle = eoRealParticle; +using Ints = eoInt, size_t>; +using Bits = eoBit, int>; + +// by enumerating candidate operators and their parameters. +eoAlgoFoundryFastGA& make_foundry( + eoFunctorStore& store, + eoInit& init, + eoEvalFunc& eval_onemax, + const size_t max_evals, + const size_t generations + ) +{ + auto& foundry = store.pack< eoAlgoFoundryFastGA >(init, eval_onemax, max_evals /*, max_restarts = max */); + + /***** Continuators ****/ + foundry.continuators.add< eoGenContinue >(generations); + // for(size_t i=1; i<10; i++) { + // foundry.continuators.add< eoGenContinue >(i); + // } + // for(size_t i=10; i < 100; i+=2 ) { + // foundry.continuators.add< eoSteadyFitContinue >(10,i); + // } + + for(double i=0.1; i<1.0; i+=0.1) { + foundry.crossover_rates.add(i); + foundry.mutation_rates.add(i); + } + + for(size_t i=5; i<100; i+=10) { + foundry.pop_sizes.add(i); + } + + /***** Crossovers ****/ + for(double i=0.1; i<0.9; i+=0.1) { + foundry.crossovers.add< eoUBitXover >(i); // preference over 1 + } + for(size_t i=1; i < 11; i+=1) { + foundry.crossovers.add< eoNPtsBitXover >(i); // nb of points + } + foundry.crossovers.add< eo1PtBitXover >(); + + /***** Mutations ****/ + double p = 1.0; // Probability of flipping eath bit. + foundry.mutations.add< eoUniformBitMutation >(p); // proba of flipping k bits, k drawn in uniform distrib + foundry.mutations.add< eoStandardBitMutation >(p); // proba of flipping k bits, k drawn in binomial distrib + foundry.mutations.add< eoConditionalBitMutation >(p); // proba of flipping k bits, k drawn in binomial distrib, minus zero + foundry.mutations.add< eoShiftedBitMutation >(p); // proba of flipping k bits, k drawn in binomial distrib, changing zeros to one + foundry.mutations.add< eoNormalBitMutation >(p); // proba of flipping k bits, k drawn in normal distrib + foundry.mutations.add< eoFastBitMutation >(p); // proba of flipping k bits, k drawn in powerlaw distrib + for(size_t i=1; i < 11; i+=1) { + foundry.mutations.add< eoDetSingleBitFlip >(i); // mutate k bits without duplicates + } + + /***** Selectors *****/ + foundry.selectors.add< eoRandomSelect >(); + foundry.selectors.add< eoSequentialSelect >(); + foundry.selectors.add< eoProportionalSelect >(); + for(size_t i=2; i < 10; i+=1) { // Tournament size. + foundry.selectors.add< eoDetTournamentSelect >(i); + } + for(double i=0.51; i<0.91; i+=0.1) { // Tournament size as perc of pop. + foundry.selectors.add< eoStochTournamentSelect >(i); + } + + /***** Replacements ****/ + foundry.replacements.add< eoPlusReplacement >(); + foundry.replacements.add< eoCommaReplacement >(); + foundry.replacements.add< eoSSGAWorseReplacement >(); + for(double i=0.51; i<0.91; i+=0.1) { + foundry.replacements.add< eoSSGAStochTournamentReplacement >(i); + } + for(size_t i=2; i < 10; i+=1) { + foundry.replacements.add< eoSSGADetTournamentReplacement >(i); + } + + return foundry; +} + +Bits::Fitness fake_func(const Bits&) { return 0; } + + +int main(int argc, char* argv[]) +{ + /***** Global parameters. *****/ + enum { ERROR_USAGE = 100 }; + + const size_t dimension = 1000; + const size_t max_evals = 2 * dimension; + const size_t buckets = 100; + + eoFunctorStore store; + + /***** Parameters managed by the caller. *****/ + assert(argc == 11); + const int pb_instance = std::atoi(argv[1]); + + std::string s(argv[2]); + eo::rng.reseed(std::stoull(s)); + + Ints encoded_algo(8); + encoded_algo[0] = std::atoi(argv[3]); // continuator + encoded_algo[1] = std::atoi(argv[4]); // crossover_rate + encoded_algo[2] = std::atoi(argv[5]); // crossover + encoded_algo[3] = std::atoi(argv[6]); // mutation_rate + encoded_algo[4] = std::atoi(argv[7]); // mutation + encoded_algo[5] = std::atoi(argv[8]); // selection + encoded_algo[6] = std::atoi(argv[9]); // pop_size + encoded_algo[7] = std::atoi(argv[10]); // replacement + + const size_t pop_size = encoded_algo[6]; + const size_t generations = max_evals / pop_size; + + eo::log << eo::setlevel(eo::warnings); + + /***** IOH logger *****/ + IOHprofiler_RangeLinear target_range(0, dimension, buckets); + IOHprofiler_RangeLinear budget_range(0, max_evals, buckets); + IOHprofiler_ecdf_logger logger(target_range, budget_range); + + logger.set_complete_flag(true); + logger.set_interval(0); + logger.activate_logger(); + + /***** IOH problem *****/ + double w_model_suite_dummy_para = 0; + int w_model_suite_epitasis_para = 0; + int w_model_suite_neutrality_para = 0; + int w_model_suite_ruggedness_para = 0; + + W_Model_OneMax w_model_om; + std::string problem_name = "OneMax"; + problem_name = problem_name + + "_D" + std::to_string((int)(w_model_suite_dummy_para * dimension)) + + "_E" + std::to_string(w_model_suite_epitasis_para) + + "_N" + std::to_string(w_model_suite_neutrality_para) + + "_R" + std::to_string(w_model_suite_ruggedness_para); + + /// This must be called to configure the w-model to be tested. + w_model_om.set_w_setting(w_model_suite_dummy_para,w_model_suite_epitasis_para, + w_model_suite_neutrality_para,w_model_suite_ruggedness_para); + + /// Set problem_name based on the configuration. + w_model_om.IOHprofiler_set_problem_name(problem_name); + + /// Set problem_id as 1 + w_model_om.IOHprofiler_set_problem_id(1); + w_model_om.IOHprofiler_set_instance_id(pb_instance); + + /// Set dimension. + w_model_om.IOHprofiler_set_number_of_variables(dimension); + + /***** Bindings *****/ + logger.track_problem(w_model_om); + + eoEvalIOHproblem onemax_eval(w_model_om, logger); + eoPopLoopEval pop_onemax(onemax_eval); + + /***** Instanciate and run the algo *****/ + + eoUniformGenerator ugen(0, 1); + eoInitFixedLength onemax_init(/*bitstring size=*/dimension, ugen); + auto& foundry = make_foundry(store, onemax_init, onemax_eval, max_evals, generations); + + size_t n = foundry.continuators.size() * foundry.crossovers.size() * foundry.mutations.size() * foundry.selectors.size() * foundry.replacements.size(); + std::clog << n << " possible algorithms instances." << std::endl; + + // Evaluation of a forged encoded_algo on the sub-problem + eoEvalFoundryFastGA eval_foundry( + foundry, onemax_init, pop_onemax, /*penalization=*/ 0); + + // Actually instanciate and run the algorithm. + eval_foundry(encoded_algo); + + /***** IOH perf stats *****/ + IOHprofiler_ecdf_sum ecdf_sum; + // iRace expects minimization + size_t perf = -1 * ecdf_sum(logger.data()); + + // Output + std::cout << perf << std::endl; +}