Merge branch 'irace-interface'
This commit is contained in:
commit
ce10a6d4d2
35 changed files with 2024 additions and 137 deletions
97
eo/contrib/irace/CMakeLists.txt
Normal file
97
eo/contrib/irace/CMakeLists.txt
Normal file
|
|
@ -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})
|
||||
|
||||
417
eo/contrib/irace/fastga.cpp
Normal file
417
eo/contrib/irace/fastga.cpp
Normal file
|
|
@ -0,0 +1,417 @@
|
|||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
#include <eo>
|
||||
#include <ga.h>
|
||||
#include <utils/checkpointing>
|
||||
#include <eoInt.h>
|
||||
#include <problems/eval/eoEvalIOH.h>
|
||||
|
||||
#include <IOHprofiler_ecdf_logger.h>
|
||||
#include <f_w_model_one_max.hpp>
|
||||
|
||||
// using Particle = eoRealParticle<eoMaximizingFitness>;
|
||||
using Ints = eoInt<eoMaximizingFitnessT<int>, size_t>;
|
||||
using Bits = eoBit<eoMaximizingFitnessT<int>, int>;
|
||||
|
||||
// by enumerating candidate operators and their parameters.
|
||||
eoAlgoFoundryFastGA<Bits>& make_foundry(
|
||||
eoFunctorStore& store,
|
||||
eoInit<Bits>& init,
|
||||
eoEvalFunc<Bits>& eval_onemax,
|
||||
const size_t max_evals,
|
||||
const size_t generations
|
||||
)
|
||||
{
|
||||
// FIXME using max_restarts>1 does not allow to honor max evals.
|
||||
auto& foundry = store.pack< eoAlgoFoundryFastGA<Bits> >(init, eval_onemax, max_evals, /*max_restarts=*/1);
|
||||
|
||||
/***** Continuators ****/
|
||||
foundry.continuators.add< eoGenContinue<Bits> >(generations);
|
||||
// for(size_t i=1; i<10; i++) {
|
||||
// foundry.continuators.add< eoGenContinue<Bits> >(i);
|
||||
// }
|
||||
// for(size_t i=10; i < 100; i+=2 ) {
|
||||
// foundry.continuators.add< eoSteadyFitContinue<Bits> >(10,i);
|
||||
// }
|
||||
|
||||
for(double i=0.0; i<1.0; i+=0.2) {
|
||||
foundry.crossover_rates.add<double>(i);
|
||||
foundry.mutation_rates.add<double>(i);
|
||||
}
|
||||
|
||||
/***** Offsprings size *****/
|
||||
// for(size_t i=5; i<100; i+=10) {
|
||||
// foundry.offspring_sizes.add<size_t>(i);
|
||||
// }
|
||||
|
||||
foundry.offspring_sizes.add<size_t>(0); // 0 = use parents fixed pop size.
|
||||
|
||||
/***** Crossovers ****/
|
||||
for(double i=0.1; i<1.0; i+=0.2) {
|
||||
foundry.crossovers.add< eoUBitXover<Bits> >(i); // preference over 1
|
||||
}
|
||||
for(size_t i=1; i < 10; i+=2) {
|
||||
|
||||
foundry.crossovers.add< eoNPtsBitXover<Bits> >(i); // nb of points
|
||||
}
|
||||
foundry.crossovers.add< eo1PtBitXover<Bits> >();
|
||||
|
||||
/***** Mutations ****/
|
||||
double p = 1.0; // Probability of flipping eath bit.
|
||||
foundry.mutations.add< eoUniformBitMutation<Bits> >(p); // proba of flipping k bits, k drawn in uniform distrib
|
||||
foundry.mutations.add< eoStandardBitMutation<Bits> >(p); // proba of flipping k bits, k drawn in binomial distrib
|
||||
foundry.mutations.add< eoConditionalBitMutation<Bits> >(p); // proba of flipping k bits, k drawn in binomial distrib, minus zero
|
||||
foundry.mutations.add< eoShiftedBitMutation<Bits> >(p); // proba of flipping k bits, k drawn in binomial distrib, changing zeros to one
|
||||
foundry.mutations.add< eoNormalBitMutation<Bits> >(p); // proba of flipping k bits, k drawn in normal distrib
|
||||
foundry.mutations.add< eoFastBitMutation<Bits> >(p); // proba of flipping k bits, k drawn in powerlaw distrib
|
||||
for(size_t i=1; i < 11; i+=2) {
|
||||
foundry.mutations.add< eoDetSingleBitFlip<Bits> >(i); // mutate k bits without duplicates
|
||||
}
|
||||
|
||||
/***** Selectors *****/
|
||||
for(eoOperatorFoundry<eoSelectOne<Bits>>& ops :
|
||||
{std::ref(foundry.crossover_selectors),
|
||||
std::ref(foundry.mutation_selectors) }) {
|
||||
|
||||
ops.add< eoRandomSelect<Bits> >();
|
||||
ops.add< eoStochTournamentSelect<Bits> >(0.5);
|
||||
ops.add< eoSequentialSelect<Bits> >();
|
||||
ops.add< eoProportionalSelect<Bits> >();
|
||||
for(size_t i=2; i < 11; i+=4) {
|
||||
ops.add< eoDetTournamentSelect<Bits> >(i);
|
||||
}
|
||||
}
|
||||
|
||||
foundry.aftercross_selectors.add< eoRandomSelect<Bits> >();
|
||||
|
||||
|
||||
/***** Replacements ****/
|
||||
foundry.replacements.add< eoPlusReplacement<Bits> >();
|
||||
foundry.replacements.add< eoCommaReplacement<Bits> >();
|
||||
foundry.replacements.add< eoSSGAWorseReplacement<Bits> >();
|
||||
for(double i=0.51; i<0.92; i+=0.2) {
|
||||
foundry.replacements.add< eoSSGAStochTournamentReplacement<Bits> >(i);
|
||||
}
|
||||
for(size_t i=2; i < 11; i+=2) {
|
||||
foundry.replacements.add< eoSSGADetTournamentReplacement<Bits> >(i);
|
||||
}
|
||||
|
||||
return foundry;
|
||||
}
|
||||
|
||||
Bits::Fitness fake_func(const Bits&) { return 0; }
|
||||
|
||||
void print_param_range(const eoParam& param, const size_t slot_size, std::ostream& out = std::cout)
|
||||
{
|
||||
// If there is no choice to be made on this operator, comment it out.
|
||||
if(slot_size - 1 <= 0) {
|
||||
out << "# ";
|
||||
}
|
||||
|
||||
// irace doesn't support "-" in names.
|
||||
std::string irace_name = param.longName();
|
||||
irace_name.erase(std::remove(irace_name.begin(), irace_name.end(), '-'), irace_name.end());
|
||||
|
||||
out << irace_name
|
||||
<< "\t\"--" << param.longName() << "=\""
|
||||
<< "\ti";
|
||||
|
||||
if(slot_size -1 <= 0) {
|
||||
out << "\t(0)";
|
||||
} else {
|
||||
out << "\t(0," << slot_size-1 << ")";
|
||||
}
|
||||
out << std::endl;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
/***** Global parameters. *****/
|
||||
enum { NO_ERROR = 0, ERROR_USAGE = 100 };
|
||||
|
||||
eoFunctorStore store;
|
||||
|
||||
eoParser parser(argc, argv, "FastGA interface for iRace");
|
||||
|
||||
const size_t dimension = parser.getORcreateParam<size_t>(1000,
|
||||
"dimension", "Dimension size",
|
||||
'd', "Problem").value();
|
||||
|
||||
const size_t max_evals = parser.getORcreateParam<size_t>(2 * dimension,
|
||||
"max-evals", "Maximum number of evaluations",
|
||||
'e', "Stopping criterion").value();
|
||||
|
||||
const size_t buckets = parser.getORcreateParam<size_t>(100,
|
||||
"buckets", "Number of buckets for discretizing the ECDF",
|
||||
'b', "Performance estimation").value();
|
||||
|
||||
uint32_t seed =
|
||||
parser.getORcreateParam<uint32_t>(0,
|
||||
"seed", "Random number seed (0 = epoch)",
|
||||
'S').value();
|
||||
if(seed == 0) {
|
||||
seed = time(0);
|
||||
}
|
||||
// rng is a global
|
||||
rng.reseed(seed);
|
||||
|
||||
|
||||
auto problem_p = parser.getORcreateParam<size_t>(0,
|
||||
"problem", "Problem ID",
|
||||
'p', "Problem", /*required=*/true);
|
||||
const size_t problem = problem_p.value();
|
||||
|
||||
|
||||
auto pop_size_p = parser.getORcreateParam<size_t>(1,
|
||||
"pop-size", "Population size",
|
||||
'P', "Operator Choice", /*required=*/false);
|
||||
const size_t pop_size = pop_size_p.value();
|
||||
|
||||
auto instance_p = parser.getORcreateParam<size_t>(0,
|
||||
"instance", "Instance ID",
|
||||
'i', "Instance", /*required=*/false);
|
||||
const size_t instance = instance_p.value();
|
||||
|
||||
auto continuator_p = parser.getORcreateParam<size_t>(0,
|
||||
"continuator", "Stopping criterion",
|
||||
'o', "Operator Choice", /*required=*/false); // Single alternative, not required.
|
||||
const size_t continuator = continuator_p.value();
|
||||
|
||||
auto crossover_rate_p = parser.getORcreateParam<size_t>(0,
|
||||
"crossover-rate", "",
|
||||
'C', "Operator Choice", /*required=*/true);
|
||||
const size_t crossover_rate = crossover_rate_p.value();
|
||||
|
||||
auto crossover_selector_p = parser.getORcreateParam<size_t>(0,
|
||||
"cross-selector", "How to selects candidates for cross-over",
|
||||
's', "Operator Choice", /*required=*/true);
|
||||
const size_t crossover_selector = crossover_selector_p.value();
|
||||
|
||||
auto crossover_p = parser.getORcreateParam<size_t>(0,
|
||||
"crossover", "",
|
||||
'c', "Operator Choice", /*required=*/true);
|
||||
const size_t crossover = crossover_p.value();
|
||||
|
||||
auto aftercross_selector_p = parser.getORcreateParam<size_t>(0,
|
||||
"aftercross-selector", "How to selects between the two individuals altered by cross-over which one will mutate",
|
||||
'a', "Operator Choice", /*required=*/false); // Single alternative, not required.
|
||||
const size_t aftercross_selector = aftercross_selector_p.value();
|
||||
|
||||
auto mutation_rate_p = parser.getORcreateParam<size_t>(0,
|
||||
"mutation-rate", "",
|
||||
'M', "Operator Choice", /*required=*/true);
|
||||
const size_t mutation_rate = mutation_rate_p.value();
|
||||
|
||||
auto mutation_selector_p = parser.getORcreateParam<size_t>(0,
|
||||
"mut-selector", "How to selects candidate for mutation",
|
||||
'u', "Operator Choice", /*required=*/true);
|
||||
const size_t mutation_selector = mutation_selector_p.value();
|
||||
|
||||
auto mutation_p = parser.getORcreateParam<size_t>(0,
|
||||
"mutation", "",
|
||||
'm', "Operator Choice", /*required=*/true);
|
||||
const size_t mutation = mutation_p.value();
|
||||
|
||||
auto replacement_p = parser.getORcreateParam<size_t>(0,
|
||||
"replacement", "",
|
||||
'r', "Operator Choice", /*required=*/true);
|
||||
const size_t replacement = replacement_p.value();
|
||||
|
||||
auto offspring_size_p = parser.getORcreateParam<size_t>(0,
|
||||
"offspring-size", "Offsprings size (0 = same size than the parents pop, see --pop-size)",
|
||||
'O', "Operator Choice", /*required=*/false); // Single alternative, not required.
|
||||
const size_t offspring_size = offspring_size_p.value();
|
||||
|
||||
|
||||
// Help + Verbose routines
|
||||
make_verbose(parser);
|
||||
make_help(parser, /*exit_after*/false, std::clog);
|
||||
|
||||
if(parser.userNeedsHelp()) {
|
||||
|
||||
// Fake operators, just to be able to call make_foundry
|
||||
// to get the configured operators slots.
|
||||
eoEvalFuncPtr<Bits> fake_eval(fake_func);
|
||||
eoUniformGenerator<int> fake_gen(0, 1);
|
||||
eoInitFixedLength<Bits> fake_init(/*bitstring size=*/1, fake_gen);
|
||||
auto fake_foundry = make_foundry(store, fake_init, fake_eval, max_evals, /*generations=*/ 1);
|
||||
|
||||
size_t n =
|
||||
fake_foundry.crossover_rates.size()
|
||||
* fake_foundry.crossover_selectors.size()
|
||||
* fake_foundry.crossovers.size()
|
||||
* fake_foundry.aftercross_selectors.size()
|
||||
* fake_foundry.mutation_rates.size()
|
||||
* fake_foundry.mutation_selectors.size()
|
||||
* fake_foundry.mutations.size()
|
||||
* fake_foundry.replacements.size()
|
||||
* fake_foundry.continuators.size()
|
||||
* fake_foundry.offspring_sizes.size();
|
||||
std::clog << std::endl;
|
||||
std::clog << n << " possible algorithms configurations." << std::endl;
|
||||
|
||||
std::clog << "Ranges of configurable parameters (redirect the stdout in a file to use it with iRace): " << std::endl;
|
||||
|
||||
// Do not print problem and instances, as they are managed separately by irace.
|
||||
std::cout << "# name\tswitch\ttype\trange" << std::endl;
|
||||
print_param_range( continuator_p, fake_foundry.continuators .size(), std::cout);
|
||||
print_param_range( crossover_rate_p, fake_foundry.crossover_rates .size(), std::cout);
|
||||
print_param_range( crossover_selector_p, fake_foundry.crossover_selectors .size(), std::cout);
|
||||
print_param_range(aftercross_selector_p, fake_foundry.aftercross_selectors.size(), std::cout);
|
||||
print_param_range( crossover_p, fake_foundry.crossovers .size(), std::cout);
|
||||
print_param_range( mutation_rate_p, fake_foundry.mutation_rates .size(), std::cout);
|
||||
print_param_range( mutation_selector_p, fake_foundry.mutation_selectors .size(), std::cout);
|
||||
print_param_range( mutation_p, fake_foundry.mutations .size(), std::cout);
|
||||
print_param_range( replacement_p, fake_foundry.replacements .size(), std::cout);
|
||||
print_param_range( offspring_size_p, fake_foundry.offspring_sizes .size(), std::cout);
|
||||
|
||||
// std::ofstream irace_param("fastga.params");
|
||||
// irace_param << "# name\tswitch\ttype\tvalues" << std::endl;
|
||||
|
||||
exit(NO_ERROR);
|
||||
}
|
||||
|
||||
const size_t generations = static_cast<size_t>(std::floor(
|
||||
static_cast<double>(max_evals) / static_cast<double>(pop_size)));
|
||||
// const size_t generations = std::numeric_limits<size_t>::max();
|
||||
eo::log << eo::debug << "Number of generations: " << generations << std::endl;
|
||||
|
||||
// Problem configuration code.
|
||||
struct Problem {
|
||||
double dummy;
|
||||
size_t epistasis;
|
||||
size_t neutrality;
|
||||
size_t ruggedness;
|
||||
size_t max_target;
|
||||
};
|
||||
|
||||
std::map<size_t, Problem> problem_config_mapping {
|
||||
{ 0, {0, 0, 1, 0, 1000}},
|
||||
{ 1, {0, 0, 3, 0, 333}},
|
||||
{ 2, {0, 0, 5, 0, 200}},
|
||||
{ 3, {0, 2, 1, 0, 1000}},
|
||||
{ 4, {0, 2, 3, 0, 333}},
|
||||
{ 5, {0, 2, 3, 0, 200}},
|
||||
{ 6, {0, 4, 1, 0, 1000}},
|
||||
{ 7, {0, 4, 3, 0, 333}},
|
||||
{ 8, {0, 4, 5, 0, 200}},
|
||||
{ 9, {0.5, 0, 1, 0, 500}},
|
||||
{10, {0.5, 0, 3, 0, 166}},
|
||||
{11, {0.5, 0, 5, 0, 100}},
|
||||
{12, {0.5, 2, 1, 0, 500}},
|
||||
{13, {0.5, 2, 3, 0, 166}},
|
||||
{14, {0.5, 2, 5, 0, 100}},
|
||||
{15, {0.5, 4, 1, 0, 500}},
|
||||
{16, {0.5, 4, 3, 0, 166}},
|
||||
{17, {0.5, 4, 5, 0, 100}},
|
||||
};
|
||||
|
||||
assert(0 <= problem and problem < problem_config_mapping.size());
|
||||
|
||||
/***** IOH logger *****/
|
||||
auto max_target_para = problem_config_mapping[problem].max_target;
|
||||
IOHprofiler_RangeLinear<size_t> target_range(0, max_target_para, buckets);
|
||||
IOHprofiler_RangeLinear<size_t> budget_range(0, max_evals, buckets);
|
||||
IOHprofiler_ecdf_logger<int, size_t, size_t> logger(
|
||||
target_range, budget_range,
|
||||
/*use_known_optimum*/false);
|
||||
|
||||
logger.set_complete_flag(true);
|
||||
logger.set_interval(0);
|
||||
logger.activate_logger();
|
||||
|
||||
/***** IOH problem *****/
|
||||
double w_model_suite_dummy_para = problem_config_mapping[problem].dummy;
|
||||
int w_model_suite_epitasis_para = problem_config_mapping[problem].epistasis;
|
||||
int w_model_suite_neutrality_para = problem_config_mapping[problem].neutrality;
|
||||
int w_model_suite_ruggedness_para = problem_config_mapping[problem].ruggedness;
|
||||
|
||||
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(problem); // FIXME check what that means
|
||||
// w_model_om.IOHprofiler_set_instance_id(instance); // FIXME changing the instance seems to change the target upper bound.
|
||||
|
||||
/// Set dimension.
|
||||
w_model_om.IOHprofiler_set_number_of_variables(dimension);
|
||||
|
||||
/***** Bindings *****/
|
||||
logger.track_problem(w_model_om);
|
||||
|
||||
eoEvalIOHproblem<Bits> onemax_pb(w_model_om, logger);
|
||||
|
||||
// eoEvalPrint<Bits> eval_print(onemax_pb, std::clog, "\n");
|
||||
eoEvalFuncCounter<Bits> eval_count(onemax_pb);
|
||||
|
||||
eoPopLoopEval<Bits> onemax_eval(eval_count);
|
||||
|
||||
/***** Instanciate and run the algo *****/
|
||||
|
||||
eoBooleanGenerator<int> bgen;
|
||||
eoInitFixedLength<Bits> onemax_init(/*bitstring size=*/dimension, bgen);
|
||||
auto& foundry = make_foundry(store, onemax_init, eval_count, max_evals - pop_size, generations);
|
||||
|
||||
Ints encoded_algo(foundry.size());
|
||||
|
||||
encoded_algo[foundry.crossover_rates .index()] = crossover_rate;
|
||||
encoded_algo[foundry.crossover_selectors .index()] = crossover_selector;
|
||||
encoded_algo[foundry.crossovers .index()] = crossover;
|
||||
encoded_algo[foundry.aftercross_selectors.index()] = aftercross_selector;
|
||||
encoded_algo[foundry.mutation_rates .index()] = mutation_rate;
|
||||
encoded_algo[foundry.mutation_selectors .index()] = mutation_selector;
|
||||
encoded_algo[foundry.mutations .index()] = mutation;
|
||||
encoded_algo[foundry.replacements .index()] = replacement;
|
||||
encoded_algo[foundry.continuators .index()] = continuator;
|
||||
encoded_algo[foundry.offspring_sizes .index()] = offspring_size;
|
||||
|
||||
std::clog << "Encoded algorithm:" << std::endl;
|
||||
foundry.select(encoded_algo);
|
||||
std::clog << foundry.name() << std::endl;
|
||||
|
||||
// // Evaluation of a forged encoded_algo on the sub-problem
|
||||
// eoEvalFoundryFastGA<Ints, Bits> eval_foundry(
|
||||
// foundry, pop_size,
|
||||
// onemax_init, onemax_eval,
|
||||
// /*penalization=*/ dimension, // Worst case penalization.
|
||||
// /*normalized=*/ false); // Use direct integer encoding.
|
||||
//
|
||||
// // Actually instanciate and run the algorithm.
|
||||
// eval_foundry(encoded_algo);
|
||||
|
||||
eoPop<Bits> pop;
|
||||
pop.append(pop_size, onemax_init);
|
||||
onemax_eval(pop,pop);
|
||||
foundry(pop); // Actually run the selected algorithm.
|
||||
|
||||
/***** IOH perf stats *****/
|
||||
IOHprofiler_ecdf_sum ecdf_sum;
|
||||
// iRace expects minimization
|
||||
long perf = ecdf_sum(logger.data());
|
||||
|
||||
// assert(0 < perf and perf <= buckets*buckets);
|
||||
if(perf <= 0 or buckets*buckets < perf) {
|
||||
std::cerr << "WARNING: illogical performance: " << perf
|
||||
<< ", check the bounds or the algorithm." << std::endl;
|
||||
}
|
||||
|
||||
// std::clog << "After " << eval_count.getValue() << " / " << max_evals << " evaluations" << std::endl;
|
||||
|
||||
// Output
|
||||
std::cout << -1 * perf << std::endl;
|
||||
|
||||
}
|
||||
87
eo/contrib/irace/irace-algo-search/target-runner
Executable file
87
eo/contrib/irace/irace-algo-search/target-runner
Executable file
|
|
@ -0,0 +1,87 @@
|
|||
#!/bin/bash
|
||||
###############################################################################
|
||||
# This script is the command that is executed every run.
|
||||
# Check the examples in examples/
|
||||
#
|
||||
# This script is run in the execution directory (execDir, --exec-dir).
|
||||
#
|
||||
# PARAMETERS:
|
||||
# $1 is the candidate configuration number
|
||||
# $2 is the instance ID
|
||||
# $3 is the seed
|
||||
# $4 is the instance name
|
||||
# The rest ($* after `shift 4') are parameters to the run
|
||||
#
|
||||
# RETURN VALUE:
|
||||
# This script should print one numerical value: the cost that must be minimized.
|
||||
# Exit with 0 if no error, with 1 in case of error
|
||||
###############################################################################
|
||||
error() {
|
||||
echo "`TZ=UTC date`: $0: error: $@"
|
||||
exit 1
|
||||
}
|
||||
|
||||
|
||||
EXE="/home/aaziz-alaoui/Documents/GitHub/paradiseo/eo/contrib/irace/irace-algo-search/bin/fastga"
|
||||
|
||||
FIXED_PARAMS=""
|
||||
|
||||
CONFIG_ID=$1
|
||||
INSTANCE_ID=$2
|
||||
SEED=$3
|
||||
INSTANCE=$4
|
||||
CROSSOVER_RATE=$5
|
||||
CROSSOVER_SELECTOR=$6
|
||||
CROSSOVER=$7
|
||||
MUTATION_RATE=$8
|
||||
MUT_SELECTOR=$9
|
||||
MUTATION=${10}
|
||||
REPLACEMENT=${11}
|
||||
shift 11 || error "Not enough parameters"
|
||||
|
||||
CONFIG_PARAMS=$*
|
||||
|
||||
STDOUT=c${CONFIG_ID}-${INSTANCE_ID}-${SEED}.stdout
|
||||
STDERR=c${CONFIG_ID}-${INSTANCE_ID}-${SEED}.stderr
|
||||
|
||||
if [ ! -x "${EXE}" ]; then
|
||||
error "${EXE}: not found or not executable (pwd: $(pwd))"
|
||||
fi
|
||||
|
||||
# If the program just prints a number, we can use 'exec' to avoid
|
||||
# creating another process, but there can be no other commands after exec.
|
||||
#exec $EXE ${FIXED_PARAMS} -i $INSTANCE ${CONFIG_PARAMS}
|
||||
# exit 1
|
||||
#
|
||||
# Otherwise, save the output to a file, and parse the result from it.
|
||||
# (If you wish to ignore segmentation faults you can use '{}' around
|
||||
# the command.)
|
||||
$EXE ${FIXED_PARAMS} --instance=$INSTANCE --seed=${SEED} --crossover-rate=${CROSSOVER_RATE} --cross-selector=${CROSSOVER_SELECTOR} --crossover=${CROSSOVER} --mutation-rate=${MUTATION_RATE} --mut-selector=${MUT_SELECTOR} --mutation=${MUTATION} --replacement=${REPLACEMENT} 1> ${STDOUT} 2> ${STDERR}
|
||||
|
||||
#echo ${cmd}
|
||||
|
||||
|
||||
# --instance=$INSTANCE --seed=$SEED
|
||||
# remplacer config param par la même config que seed et instance id
|
||||
|
||||
|
||||
|
||||
# This may be used to introduce a delay if there are filesystem
|
||||
# issues.
|
||||
#SLEEPTIME=1
|
||||
#while [ ! -s "${STDOUT}" ]; do
|
||||
# sleep $SLEEPTIME
|
||||
# let "SLEEPTIME += 1"
|
||||
#done
|
||||
|
||||
# This is an example of reading a number from the output.
|
||||
# It assumes that the objective value is the first number in
|
||||
# the first column of the last line of the output.
|
||||
if [ -s "${STDOUT}" ]; then
|
||||
COST=$(tail -n 1 ${STDOUT} | grep -e '^[[:space:]]*[+-]\?[0-9]' | cut -f1)
|
||||
echo "$COST"
|
||||
rm -f "${STDOUT}" "${STDERR}"
|
||||
exit 0
|
||||
else
|
||||
error "${STDOUT}: No such file or directory"
|
||||
fi
|
||||
48
eo/contrib/irace/irace-config/default.instances
Normal file
48
eo/contrib/irace/irace-config/default.instances
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
## This is an example of specifying instances with a file.
|
||||
|
||||
# Each line is an instance relative to trainInstancesDir
|
||||
# (see scenario.txt.tmpl) and an optional sequence of instance-specific
|
||||
# parameters that will be passed to target-runnerx when invoked on that
|
||||
# instance.
|
||||
|
||||
0
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
7
|
||||
8
|
||||
9
|
||||
10
|
||||
11
|
||||
12
|
||||
13
|
||||
14
|
||||
15
|
||||
16
|
||||
17
|
||||
18
|
||||
19
|
||||
20
|
||||
21
|
||||
22
|
||||
23
|
||||
24
|
||||
25
|
||||
26
|
||||
27
|
||||
28
|
||||
29
|
||||
30
|
||||
31
|
||||
32
|
||||
33
|
||||
34
|
||||
35
|
||||
36
|
||||
37
|
||||
38
|
||||
39
|
||||
40
|
||||
227
eo/contrib/irace/irace-config/example.scen
Normal file
227
eo/contrib/irace/irace-config/example.scen
Normal file
|
|
@ -0,0 +1,227 @@
|
|||
###################################################### -*- mode: r -*- #####
|
||||
## Scenario setup for Iterated Race (irace).
|
||||
############################################################################
|
||||
|
||||
## To use the default value of a parameter of iRace, simply do not set
|
||||
## the parameter (comment it out in this file, and do not give any
|
||||
## value on the command line).
|
||||
|
||||
## File that contains the description of the parameters of the target
|
||||
## algorithm.
|
||||
parameterFile = "./fastga.param"
|
||||
|
||||
## Directory where the programs will be run.
|
||||
execDir = "."
|
||||
|
||||
## File to save tuning results as an R dataset, either absolute path or
|
||||
## relative to execDir.
|
||||
# logFile = "./irace.Rdata"
|
||||
|
||||
## Previously saved log file to recover the execution of irace, either
|
||||
## absolute path or relative to the current directory. If empty or NULL,
|
||||
## recovery is not performed.
|
||||
# recoveryFile = ""
|
||||
|
||||
## Directory where training instances are located; either absolute path or
|
||||
## relative to current directory. If no trainInstancesFiles is provided,
|
||||
## all the files in trainInstancesDir will be listed as instances.
|
||||
trainInstancesDir = "."
|
||||
|
||||
## File that contains a list of training instances and optionally
|
||||
## additional parameters for them. If trainInstancesDir is provided, irace
|
||||
## will search for the files in this folder.
|
||||
trainInstancesFile = "./default.instances"
|
||||
|
||||
## File that contains a table of initial configurations. If empty or NULL,
|
||||
## all initial configurations are randomly generated.
|
||||
# configurationsFile = ""
|
||||
|
||||
## File that contains a list of logical expressions that cannot be TRUE
|
||||
## for any evaluated configuration. If empty or NULL, do not use forbidden
|
||||
## expressions.
|
||||
# forbiddenFile = ""
|
||||
|
||||
## Script called for each configuration that executes the target algorithm
|
||||
## to be tuned. See templates.
|
||||
targetRunner = "./target-runner"
|
||||
|
||||
## Number of times to retry a call to targetRunner if the call failed.
|
||||
# targetRunnerRetries = 0
|
||||
|
||||
## Optional data passed to targetRunner. This is ignored by the default
|
||||
## targetRunner function, but it may be used by custom targetRunner
|
||||
## functions to pass persistent data around.
|
||||
# targetRunnerData = ""
|
||||
|
||||
## Optional R function to provide custom parallelization of targetRunner.
|
||||
# targetRunnerParallel = ""
|
||||
|
||||
## Optional script or R function that provides a numeric value for each
|
||||
## configuration. See templates/target-evaluator.tmpl
|
||||
# targetEvaluator = ""
|
||||
|
||||
## Maximum number of runs (invocations of targetRunner) that will be
|
||||
## performed. It determines the maximum budget of experiments for the
|
||||
## tuning.
|
||||
maxExperiments = 2000
|
||||
|
||||
## Maximum total execution time in seconds for the executions of
|
||||
## targetRunner. targetRunner must return two values: cost and time.
|
||||
# maxTime = 60
|
||||
|
||||
## Fraction (smaller than 1) of the budget used to estimate the mean
|
||||
## computation time of a configuration. Only used when maxTime > 0
|
||||
# budgetEstimation = 0.02
|
||||
|
||||
## Maximum number of decimal places that are significant for numerical
|
||||
## (real) parameters.
|
||||
digits = 2
|
||||
|
||||
## Debug level of the output of irace. Set this to 0 to silence all debug
|
||||
## messages. Higher values provide more verbose debug messages.
|
||||
# debugLevel = 0
|
||||
|
||||
## Number of iterations.
|
||||
# nbIterations = 0
|
||||
|
||||
## Number of runs of the target algorithm per iteration.
|
||||
# nbExperimentsPerIteration = 0
|
||||
|
||||
## Randomly sample the training instances or use them in the order given.
|
||||
# sampleInstances = 1
|
||||
|
||||
## Statistical test used for elimination. Default test is always F-test
|
||||
## unless capping is enabled, in which case the default test is t-test.
|
||||
## Valid values are: F-test (Friedman test), t-test (pairwise t-tests with
|
||||
## no correction), t-test-bonferroni (t-test with Bonferroni's correction
|
||||
## for multiple comparisons), t-test-holm (t-test with Holm's correction
|
||||
## for multiple comparisons).
|
||||
# testType = "F-test"
|
||||
|
||||
## Number of instances evaluated before the first elimination test. It
|
||||
## must be a multiple of eachTest.
|
||||
# firstTest = 5
|
||||
|
||||
## Number of instances evaluated between elimination tests.
|
||||
# eachTest = 1
|
||||
|
||||
## Minimum number of configurations needed to continue the execution of
|
||||
## each race (iteration).
|
||||
# minNbSurvival = 0
|
||||
|
||||
## Number of configurations to be sampled and evaluated at each iteration.
|
||||
# nbConfigurations = 0
|
||||
|
||||
## Parameter used to define the number of configurations sampled and
|
||||
## evaluated at each iteration.
|
||||
# mu = 5
|
||||
|
||||
## Confidence level for the elimination test.
|
||||
# confidence = 0.95
|
||||
|
||||
## If the target algorithm is deterministic, configurations will be
|
||||
## evaluated only once per instance.
|
||||
# deterministic = 0
|
||||
|
||||
## Seed of the random number generator (by default, generate a random
|
||||
## seed).
|
||||
# seed = NA
|
||||
|
||||
## Number of calls to targetRunner to execute in parallel. Values 0 or 1
|
||||
## mean no parallelization.
|
||||
# parallel = 0
|
||||
|
||||
## Enable/disable load-balancing when executing experiments in parallel.
|
||||
## Load-balancing makes better use of computing resources, but increases
|
||||
## communication overhead. If this overhead is large, disabling
|
||||
## load-balancing may be faster.
|
||||
# loadBalancing = 1
|
||||
|
||||
## Enable/disable MPI. Use Rmpi to execute targetRunner in parallel
|
||||
## (parameter parallel is the number of slaves).
|
||||
# mpi = 0
|
||||
|
||||
## Specify how irace waits for jobs to finish when targetRunner submits
|
||||
## jobs to a batch cluster: sge, pbs, torque or slurm. targetRunner must
|
||||
## submit jobs to the cluster using, for example, qsub.
|
||||
# batchmode = 0
|
||||
|
||||
## Enable/disable the soft restart strategy that avoids premature
|
||||
## convergence of the probabilistic model.
|
||||
# softRestart = 1
|
||||
|
||||
## Soft restart threshold value for numerical parameters. If NA, NULL or
|
||||
## "", it is computed as 10^-digits.
|
||||
# softRestartThreshold = ""
|
||||
|
||||
## Directory where testing instances are located, either absolute or
|
||||
## relative to current directory.
|
||||
# testInstancesDir = ""
|
||||
|
||||
## File containing a list of test instances and optionally additional
|
||||
## parameters for them.
|
||||
# testInstancesFile = ""
|
||||
|
||||
## Number of elite configurations returned by irace that will be tested if
|
||||
## test instances are provided.
|
||||
# testNbElites = 1
|
||||
|
||||
## Enable/disable testing the elite configurations found at each
|
||||
## iteration.
|
||||
# testIterationElites = 0
|
||||
|
||||
## Enable/disable elitist irace.
|
||||
# elitist = 1
|
||||
|
||||
## Number of instances added to the execution list before previous
|
||||
## instances in elitist irace.
|
||||
# elitistNewInstances = 1
|
||||
|
||||
## In elitist irace, maximum number per race of elimination tests that do
|
||||
## not eliminate a configuration. Use 0 for no limit.
|
||||
# elitistLimit = 2
|
||||
|
||||
## User-defined R function that takes a configuration generated by irace
|
||||
## and repairs it.
|
||||
# repairConfiguration = ""
|
||||
|
||||
## Enable the use of adaptive capping, a technique designed for minimizing
|
||||
## the computation time of configurations. This is only available when
|
||||
## elitist is active.
|
||||
# capping = 0
|
||||
|
||||
## Measure used to obtain the execution bound from the performance of the
|
||||
## elite configurations: median, mean, worst, best.
|
||||
# cappingType = "median"
|
||||
|
||||
## Method to calculate the mean performance of elite configurations:
|
||||
## candidate or instance.
|
||||
# boundType = "candidate"
|
||||
|
||||
## Maximum execution bound for targetRunner. It must be specified when
|
||||
## capping is enabled.
|
||||
# boundMax = 0
|
||||
|
||||
## Precision used for calculating the execution time. It must be specified
|
||||
## when capping is enabled.
|
||||
# boundDigits = 0
|
||||
|
||||
## Penalization constant for timed out executions (executions that reach
|
||||
## boundMax execution time).
|
||||
# boundPar = 1
|
||||
|
||||
## Replace the configuration cost of bounded executions with boundMax.
|
||||
# boundAsTimeout = 1
|
||||
|
||||
## Percentage of the configuration budget used to perform a postselection
|
||||
## race of the best configurations of each iteration after the execution
|
||||
## of irace.
|
||||
# postselection = 0
|
||||
|
||||
## Enable/disable AClib mode. This option enables compatibility with
|
||||
## GenericWrapper4AC as targetRunner script.
|
||||
# aclib = 0
|
||||
|
||||
## END of scenario file
|
||||
############################################################################
|
||||
|
||||
87
eo/contrib/irace/irace-config/target-runner
Executable file
87
eo/contrib/irace/irace-config/target-runner
Executable file
|
|
@ -0,0 +1,87 @@
|
|||
#!/bin/bash
|
||||
###############################################################################
|
||||
# This script is the command that is executed every run.
|
||||
# Check the examples in examples/
|
||||
#
|
||||
# This script is run in the execution directory (execDir, --exec-dir).
|
||||
#
|
||||
# PARAMETERS:
|
||||
# $1 is the candidate configuration number
|
||||
# $2 is the instance ID
|
||||
# $3 is the seed
|
||||
# $4 is the instance name
|
||||
# The rest ($* after `shift 4') are parameters to the run
|
||||
#
|
||||
# RETURN VALUE:
|
||||
# This script should print one numerical value: the cost that must be minimized.
|
||||
# Exit with 0 if no error, with 1 in case of error
|
||||
###############################################################################
|
||||
error() {
|
||||
echo "`TZ=UTC date`: $0: error: $@"
|
||||
exit 1
|
||||
}
|
||||
|
||||
|
||||
EXE="./fastga"
|
||||
LOG_DIR="irace_logs"
|
||||
|
||||
FIXED_PARAMS="--problem=0"
|
||||
|
||||
CONFIG_ID=$1
|
||||
INSTANCE_ID=$2
|
||||
SEED=$3
|
||||
INSTANCE=$(echo $4 | sed 's/\//\n/g'|tail -n 1)
|
||||
CROSSOVER_RATE=$5
|
||||
CROSSOVER_SELECTOR=$6
|
||||
CROSSOVER=$7
|
||||
MUTATION_RATE=$8
|
||||
MUT_SELECTOR=$9
|
||||
MUTATION=${10}
|
||||
REPLACEMENT=${11}
|
||||
shift 11 || error "Not enough parameters"
|
||||
|
||||
INSTANCE_PARAMS=$*
|
||||
|
||||
# STDOUT=${LOG_DIR}/c${CONFIG_ID}_i${INSTANCE_ID}_s${SEED}.stdout
|
||||
# STDERR=${LOG_DIR}/c${CONFIG_ID}_i${INSTANCE_ID}_s${SEED}.stderr
|
||||
STDOUT="/dev/null"
|
||||
STDERR="/dev/null"
|
||||
|
||||
if [ ! -x "${EXE}" ]; then
|
||||
error "${EXE}: not found or not executable (pwd: $(pwd))"
|
||||
fi
|
||||
|
||||
# If the program just prints a number, we can use 'exec' to avoid
|
||||
# creating another process, but there can be no other commands after exec.
|
||||
#exec $EXE ${FIXED_PARAMS} -i $INSTANCE ${INSTANCE_PARAMS}
|
||||
# exit 1
|
||||
#
|
||||
# Otherwise, save the output to a file, and parse the result from it.
|
||||
# (If you wish to ignore segmentation faults you can use '{}' around
|
||||
# the command.)
|
||||
cmd="$EXE ${FIXED_PARAMS} --instance=${INSTANCE} --seed=${SEED} ${CROSSOVER_RATE} ${CROSSOVER_SELECTOR} ${CROSSOVER} ${MUTATION_RATE} ${MUT_SELECTOR} ${MUTATION} ${REPLACEMENT}"
|
||||
# NOTE: irace seems to capture both stderr and stdout, so you should not output to stderr
|
||||
echo ${cmd} > ${STDERR}
|
||||
$cmd 2> ${STDERR} | tee ${STDOUT}
|
||||
|
||||
# The following code is useless if the binary only output a single number on stdout.
|
||||
|
||||
# This may be used to introduce a delay if there are filesystem
|
||||
# issues.
|
||||
# SLEEPTIME=1
|
||||
# while [ ! -s "${STDOUT}" ]; do
|
||||
# sleep $SLEEPTIME
|
||||
# let "SLEEPTIME += 1"
|
||||
# done
|
||||
|
||||
# This is an example of reading a number from the output.
|
||||
# It assumes that the objective value is the first number in
|
||||
# the first column of the last line of the output.
|
||||
# if [ -s "${STDOUT}" ]; then
|
||||
# COST=$(tail -n 1 ${STDOUT} | grep -e '^[[:space:]]*[+-]\?[0-9]' | cut -f1)
|
||||
# echo "$COST"
|
||||
# rm -f "${STDOUT}" "${STDERR}"
|
||||
# exit 0
|
||||
# else
|
||||
# error "${STDOUT}: No such file or directory"
|
||||
# fi
|
||||
19
eo/contrib/irace/run_irace.sh
Executable file
19
eo/contrib/irace/run_irace.sh
Executable file
|
|
@ -0,0 +1,19 @@
|
|||
#!/bin/bash
|
||||
|
||||
if [[ $# != 1 ]] ; then
|
||||
echo "ERROR: build dir not indicated"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd $1
|
||||
pwd
|
||||
|
||||
# Fore some reason, irace absolutely need those files...
|
||||
cp ../irace-config/example.scen .
|
||||
cp ../irace-config/target-runner .
|
||||
cp ../irace-config/default.instances .
|
||||
|
||||
# Generate the parameter list file.
|
||||
./fastga -h > fastga.param 2>/dev/null
|
||||
/usr/lib/R/site-library/irace/bin/irace --scenario example.scen 2>&1 | tee irace.log
|
||||
|
||||
|
|
@ -85,6 +85,7 @@
|
|||
#include "eoEvalKeepBest.h"
|
||||
#include "eoEvalTimeThrowException.h"
|
||||
#include "eoEvalUserTimeThrowException.h"
|
||||
#include "eoEvalPrint.h"
|
||||
|
||||
// Continuators - all include eoContinue.h
|
||||
#include "eoCombinedContinue.h"
|
||||
|
|
@ -146,6 +147,7 @@
|
|||
// Algorithms
|
||||
#include "eoEasyEA.h"
|
||||
#include "eoSGA.h"
|
||||
#include "eoFastGA.h"
|
||||
// #include "eoEvolutionStrategy.h" removed for a while - until eoGenOp is done
|
||||
#include "eoAlgoReset.h"
|
||||
#include "eoAlgoRestart.h"
|
||||
|
|
@ -164,6 +166,7 @@
|
|||
#include "eoAlgoFoundryEA.h"
|
||||
#include "eoAlgoFoundryFastGA.h"
|
||||
#include "eoEvalFoundryEA.h"
|
||||
#include "eoEvalFoundryFastGA.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// to be continued ...
|
||||
|
|
|
|||
|
|
@ -76,12 +76,12 @@ class eoOperatorFoundry : public eoForgeVector< Itf >
|
|||
* In a second step, the operators to be used should be selected
|
||||
* by indicating their index, just like if the foundry was an array:
|
||||
* @code
|
||||
* foundry = {0, 1, 2};
|
||||
* // ^ ^ ^
|
||||
* // | | |
|
||||
* // | | + 3d operator
|
||||
* // | + 2d operator
|
||||
* // + 1st operator
|
||||
* foundry.select({0, 1, 2});
|
||||
* // ^ ^ ^
|
||||
* // | | |
|
||||
* // | | + 3d operator
|
||||
* // | + 2d operator
|
||||
* // + 1st operator
|
||||
* @endcode
|
||||
*
|
||||
* If you don't (want to) recall the order of the operators in the encoding,
|
||||
|
|
|
|||
|
|
@ -27,30 +27,30 @@
|
|||
#include <tuple>
|
||||
#include <limits>
|
||||
|
||||
/** A class that assemble an eoEasyEA on the fly, given a combination of available operators.
|
||||
/** A class that assemble an eoFastGA on the fly, given a combination of available operators.
|
||||
*
|
||||
* The foundry should first be set up with sets of operators
|
||||
* for the main modules of an EA:
|
||||
* continuators, crossovers, mutations, selection and replacement operators.
|
||||
* for the main modules of a FastGA:
|
||||
* continuators, crossovers, mutations, selections, replacement operators, etc.
|
||||
*
|
||||
* This is done through public member variable's `add` method,
|
||||
* which takes the class name as template and its constructor's parameters
|
||||
* as arguments. For example:
|
||||
* @code
|
||||
* foundry.selectors.add< eoStochTournamentSelect<EOT> >( 0.5 );
|
||||
* foundry.selectors.add< eoRandomSelect<EOT> >();
|
||||
* @endcode
|
||||
*
|
||||
* @warning If the constructor takes a reference YOU SHOULD ABSOLUTELY wrap it
|
||||
* in a `std::ref`, or it will silently be passed as a copy,
|
||||
* which would effectively disable any link between operators.
|
||||
* which would effectively disable any link with other operator(s).
|
||||
*
|
||||
* In a second step, the operators to be used should be selected
|
||||
* by indicating their index, passing an array of eight elements:
|
||||
* by indicating their index, passing an array of 10 elements:
|
||||
* @code
|
||||
* foundry.select({0, 1, 2, 3, 4, 5, 6, 7});
|
||||
* foundry.select({0, 1, 2, 3, 4, 5, 6, 7, 8, 9});
|
||||
* @endcode
|
||||
*
|
||||
* @note: by default, the firsts of the eight operators are selected.
|
||||
* @note: by default, the firsts of the 10 operators are selected.
|
||||
*
|
||||
* If you don't (want to) recall the order of the operators in the encoding,
|
||||
* you can use the `index()` member, for example:
|
||||
|
|
@ -58,7 +58,7 @@
|
|||
* foundry.at(foundry.continuators.index()) = 2; // select the third continuator
|
||||
* @endcode
|
||||
*
|
||||
* Now, you can call the fourdry just like any eoAlgo, by passing it an eoPop:
|
||||
* Now, you can call the foundry just like any eoAlgo, by passing it an eoPop:
|
||||
* @code
|
||||
* foundry(pop);
|
||||
* @encode
|
||||
|
|
@ -69,7 +69,7 @@
|
|||
* Every instantiation is deferred upon actual use. That way, you can still reconfigure them
|
||||
* at any time with `eoForgeOperator::setup`, for example:
|
||||
* @code
|
||||
* foundry.selector.at(0).setup(0.5); // using constructor's arguments
|
||||
* foundry.selector.at(0).setup(0.5); // Will call constructor's arguments
|
||||
* @endcode
|
||||
*
|
||||
* @ingroup Foundry
|
||||
|
|
@ -82,16 +82,26 @@ class eoAlgoFoundryFastGA : public eoAlgoFoundry<EOT>
|
|||
/** The constructon only take an eval, because all other operators
|
||||
* are stored in the public containers.
|
||||
*/
|
||||
eoAlgoFoundryFastGA( eoInit<EOT> & init, eoEvalFunc<EOT>& eval, size_t max_evals = 10000, size_t max_restarts = std::numeric_limits<size_t>::max() ) :
|
||||
eoAlgoFoundry<EOT>(8),
|
||||
continuators(0, true), // Always re-instantiate continuators, because they hold a state.
|
||||
crossover_rates(1, false),
|
||||
eoAlgoFoundryFastGA(
|
||||
eoInit<EOT> & init,
|
||||
eoEvalFunc<EOT>& eval,
|
||||
size_t max_evals = 10000,
|
||||
size_t max_restarts = std::numeric_limits<size_t>::max()
|
||||
) :
|
||||
eoAlgoFoundry<EOT>(10),
|
||||
|
||||
crossover_rates(0, false),
|
||||
crossover_selectors(1, false),
|
||||
crossovers(2, false),
|
||||
mutation_rates(3, false),
|
||||
mutations(4, false),
|
||||
selectors(5, false),
|
||||
pop_sizes(6, false),
|
||||
aftercross_selectors(3, false),
|
||||
|
||||
mutation_rates(4, false),
|
||||
mutation_selectors(5, false),
|
||||
mutations(6, false),
|
||||
|
||||
replacements(7, false),
|
||||
continuators(8, true), // Always re-instantiate continuators, because they hold a state.
|
||||
offspring_sizes(9, false),
|
||||
_eval(eval),
|
||||
_init(init),
|
||||
_max_evals(max_evals),
|
||||
|
|
@ -101,93 +111,89 @@ class eoAlgoFoundryFastGA : public eoAlgoFoundry<EOT>
|
|||
public:
|
||||
|
||||
/* Operators containers @{ */
|
||||
eoOperatorFoundry< eoContinue<EOT> > continuators;
|
||||
eoOperatorFoundry< double > crossover_rates;
|
||||
eoOperatorFoundry< eoSelectOne<EOT> > crossover_selectors;
|
||||
eoOperatorFoundry< eoQuadOp<EOT> > crossovers;
|
||||
eoOperatorFoundry< eoSelectOne<EOT> > aftercross_selectors;
|
||||
|
||||
eoOperatorFoundry< double > mutation_rates;
|
||||
eoOperatorFoundry< eoSelectOne<EOT> > mutation_selectors;
|
||||
eoOperatorFoundry< eoMonOp<EOT> > mutations;
|
||||
eoOperatorFoundry< eoSelectOne<EOT> > selectors;
|
||||
eoOperatorFoundry< size_t > pop_sizes;
|
||||
|
||||
eoOperatorFoundry< eoReplacement<EOT> > replacements;
|
||||
eoOperatorFoundry< eoContinue<EOT> > continuators;
|
||||
eoOperatorFoundry< size_t > offspring_sizes;
|
||||
/* @} */
|
||||
|
||||
/** instantiate and call the pre-selected algorithm.
|
||||
*/
|
||||
void operator()(eoPop<EOT>& pop)
|
||||
{
|
||||
assert(continuators.size() > 0); assert(this->at(continuators.index()) < continuators.size());
|
||||
assert( crossover_rates.size() > 0); assert(this->at( crossover_rates.index()) < crossover_rates.size());
|
||||
assert( crossovers.size() > 0); assert(this->at( crossovers.index()) < crossovers.size());
|
||||
assert( mutation_rates.size() > 0); assert(this->at( mutation_rates.index()) < mutation_rates.size());
|
||||
assert( mutations.size() > 0); assert(this->at( mutations.index()) < mutations.size());
|
||||
assert( selectors.size() > 0); assert(this->at( selectors.index()) < selectors.size());
|
||||
assert( pop_sizes.size() > 0); assert(this->at( pop_sizes.index()) < pop_sizes.size());
|
||||
assert(replacements.size() > 0); assert(this->at(replacements.index()) < replacements.size());
|
||||
|
||||
// Crossover or clone
|
||||
double cross_rate = this->crossover_rate();
|
||||
eoProportionalOp<EOT> cross;
|
||||
// Cross-over that produce only one offspring,
|
||||
// made by wrapping the quad op (which produce 2 offsprings)
|
||||
// in a bin op (which ignore the second offspring).
|
||||
eoQuad2BinOp<EOT> single_cross(this->crossover());
|
||||
cross.add(single_cross, cross_rate);
|
||||
eoBinCloneOp<EOT> cross_clone;
|
||||
cross.add(cross_clone, 1 - cross_rate); // Clone
|
||||
|
||||
// Mutation or clone
|
||||
double mut_rate = this->mutation_rate();
|
||||
eoProportionalOp<EOT> mut;
|
||||
mut.add(this->mutation(), mut_rate);
|
||||
eoMonCloneOp<EOT> mut_clone;
|
||||
mut.add(mut_clone, 1 - mut_rate); // FIXME TBC
|
||||
|
||||
// Apply mutation after cross-over.
|
||||
eoSequentialOp<EOT> variator;
|
||||
variator.add(cross,1.0);
|
||||
variator.add(mut,1.0);
|
||||
|
||||
// All variatiors
|
||||
double lambda = this->pop_size();
|
||||
eoGeneralBreeder<EOT> breeder(this->selector(), variator, lambda, /*as rate*/false);
|
||||
assert( crossover_rates.size() > 0); assert(this->at( crossover_rates.index()) < crossover_rates.size());
|
||||
assert( crossover_selectors.size() > 0); assert(this->at( crossover_selectors.index()) < crossover_selectors.size());
|
||||
assert( crossovers.size() > 0); assert(this->at( crossovers.index()) < crossovers.size());
|
||||
assert(aftercross_selectors.size() > 0); assert(this->at(aftercross_selectors.index()) < aftercross_selectors.size());
|
||||
assert( mutation_rates.size() > 0); assert(this->at( mutation_rates.index()) < mutation_rates.size());
|
||||
assert( mutation_selectors.size() > 0); assert(this->at( mutation_selectors.index()) < mutation_selectors.size());
|
||||
assert( mutations.size() > 0); assert(this->at( mutations.index()) < mutations.size());
|
||||
assert( replacements.size() > 0); assert(this->at( replacements.index()) < replacements.size());
|
||||
assert( continuators.size() > 0); assert(this->at( continuators.index()) < continuators.size());
|
||||
assert( offspring_sizes.size() > 0); assert(this->at( offspring_sizes.index()) < offspring_sizes.size());
|
||||
|
||||
// Objective function calls counter
|
||||
eoEvalCounterThrowException<EOT> eval(_eval, _max_evals);
|
||||
eo::log << eo::xdebug << "Evaluations: " << eval.value() << " / " << _max_evals << std::endl;
|
||||
eoPopLoopEval<EOT> pop_eval(eval);
|
||||
|
||||
// Algorithm itself
|
||||
eoEasyEA<EOT> algo = eoEasyEA<EOT>(this->continuator(), pop_eval, breeder, this->replacement());
|
||||
eoFastGA<EOT> algo(
|
||||
this->crossover_rate(),
|
||||
this->crossover_selector(),
|
||||
this->crossover(),
|
||||
this->aftercross_selector(),
|
||||
this->mutation_rate(),
|
||||
this->mutation_selector(),
|
||||
this->mutation(),
|
||||
pop_eval,
|
||||
this->replacement(),
|
||||
this->continuator(),
|
||||
this->offspring_size()
|
||||
);
|
||||
|
||||
// Restart wrapper
|
||||
eoAlgoPopReset<EOT> reset_pop(_init, pop_eval);
|
||||
eoGenContinue<EOT> restart_cont(_max_restarts);
|
||||
eoAlgoRestart<EOT> restart(eval, algo, restart_cont, reset_pop);
|
||||
// eoAlgoPopReset<EOT> reset_pop(_init, pop_eval);
|
||||
// eoGenContinue<EOT> restart_cont(_max_restarts);
|
||||
// eoAlgoRestart<EOT> restart(eval, algo, restart_cont, reset_pop);
|
||||
|
||||
try {
|
||||
restart(pop);
|
||||
// restart(pop);
|
||||
algo(pop);
|
||||
} catch(eoMaxEvalException e) {
|
||||
#ifndef NDEBUG
|
||||
eo::log << eo::debug << "Reached maximum evaluations: " << eval.getValue() << " / " << _max_evals << std::endl;
|
||||
#endif
|
||||
// In case some solutions were not evaluated when max eval occured.
|
||||
eoPopLoopEval<EOT> pop_last_eval(_eval);
|
||||
pop_last_eval(pop,pop);
|
||||
// FIXME can this even be considered legal?
|
||||
// eoPopLoopEval<EOT> pop_last_eval(_eval);
|
||||
// pop_last_eval(pop,pop);
|
||||
}
|
||||
}
|
||||
|
||||
/** Return an approximate name of the selected algorithm.
|
||||
*
|
||||
* @note: does not take into account parameters of the operators,
|
||||
* only show class names.
|
||||
*/
|
||||
std::string name()
|
||||
{
|
||||
std::ostringstream name;
|
||||
name << this->at(continuators.index()) << " (" << this->continuator().className() << ") + ";
|
||||
name << this->at(crossover_rates.index()) << " (" << this->crossover_rate().className() << ") + ";
|
||||
name << this->at(crossovers.index()) << " (" << this->crossover().className() << ") + ";
|
||||
name << this->at(mutation_rates.index()) << " (" << this->mutation_rate().className() << ") + ";
|
||||
name << this->at(mutations.index()) << " (" << this->mutation().className() << ") + ";
|
||||
name << this->at(selectors.index()) << " (" << this->selector().className() << ") + ";
|
||||
name << this->at(pop_sizes.index()) << " (" << this->pop_size().className() << ")";
|
||||
name << this->at(replacements.index()) << " (" << this->replacement().className() << ")";
|
||||
name << "crossover_rates: " << this->at( crossover_rates.index()) << " (" << this-> crossover_rate() << ") + ";
|
||||
name << "crossover_selectors: " << this->at( crossover_selectors.index()) << " (" << this-> crossover_selector().className() << ") + ";
|
||||
name << "aftercross_selector: " << this->at(aftercross_selectors.index()) << " (" << this->aftercross_selector().className() << ") + ";
|
||||
name << "crossovers: " << this->at( crossovers.index()) << " (" << this-> crossover().className() << ") + ";
|
||||
name << "mutation_rates: " << this->at( mutation_rates.index()) << " (" << this-> mutation_rate() << ") + ";
|
||||
name << "mutation_selectors: " << this->at( mutation_selectors.index()) << " (" << this-> mutation_selector().className() << ") + ";
|
||||
name << "mutations: " << this->at( mutations.index()) << " (" << this-> mutation().className() << ") + ";
|
||||
name << "replacements: " << this->at( replacements.index()) << " (" << this-> replacement().className() << ") + ";
|
||||
name << "continuators: " << this->at( continuators.index()) << " (" << this-> continuator().className() << ") + ";
|
||||
name << "offspring_sizes: " << this->at( offspring_sizes.index()) << " (" << this-> offspring_size() << ")";
|
||||
return name.str();
|
||||
}
|
||||
|
||||
|
|
@ -228,16 +234,28 @@ class eoAlgoFoundryFastGA : public eoAlgoFoundry<EOT>
|
|||
return mutations.instantiate(this->at(mutations.index()));
|
||||
}
|
||||
|
||||
eoSelectOne<EOT>& selector()
|
||||
eoSelectOne<EOT>& crossover_selector()
|
||||
{
|
||||
assert(this->at(selectors.index()) < selectors.size());
|
||||
return selectors.instantiate(this->at(selectors.index()));
|
||||
assert(this->at(crossover_selectors.index()) < crossover_selectors.size());
|
||||
return crossover_selectors.instantiate(this->at(crossover_selectors.index()));
|
||||
}
|
||||
|
||||
size_t& pop_size()
|
||||
eoSelectOne<EOT>& aftercross_selector()
|
||||
{
|
||||
assert(this->at(pop_sizes.index()) < pop_sizes.size());
|
||||
return pop_sizes.instantiate(this->at(pop_sizes.index()));
|
||||
assert(this->at(aftercross_selectors.index()) < aftercross_selectors.size());
|
||||
return aftercross_selectors.instantiate(this->at(aftercross_selectors.index()));
|
||||
}
|
||||
|
||||
eoSelectOne<EOT>& mutation_selector()
|
||||
{
|
||||
assert(this->at(mutation_selectors.index()) < mutation_selectors.size());
|
||||
return mutation_selectors.instantiate(this->at(mutation_selectors.index()));
|
||||
}
|
||||
|
||||
size_t& offspring_size()
|
||||
{
|
||||
assert(this->at(offspring_sizes.index()) < offspring_sizes.size());
|
||||
return offspring_sizes.instantiate(this->at(offspring_sizes.index()));
|
||||
}
|
||||
|
||||
eoReplacement<EOT>& replacement()
|
||||
|
|
|
|||
|
|
@ -147,6 +147,9 @@ public:
|
|||
virtual void operator()(eoPop<EOT> & pop)
|
||||
{
|
||||
do {
|
||||
#ifndef NDEBUG
|
||||
eo::log << eo::debug << "Restart" << std::endl;
|
||||
#endif
|
||||
_reseter(pop);
|
||||
_algo(pop);
|
||||
} while( _continue(pop) );
|
||||
|
|
|
|||
|
|
@ -272,7 +272,7 @@ template<class EOT> class eoEasyEA: public eoAlgo<EOT>
|
|||
|
||||
replace(_pop, offspring); // after replace, the new pop. is in _pop
|
||||
|
||||
std::cout << _pop << std::endl;
|
||||
// std::cout << _pop << std::endl;
|
||||
|
||||
if (pSize > _pop.size())
|
||||
throw eoException("Population shrinking!");
|
||||
|
|
|
|||
|
|
@ -64,20 +64,18 @@ public :
|
|||
// bypass already evaluated individuals
|
||||
if (eo.invalid()) {
|
||||
|
||||
// increment the value of the self parameter
|
||||
// (eoEvalFuncCounter inherits from @see eoValueParam)
|
||||
value()++;
|
||||
// evaluate
|
||||
this->eoEvalFuncCounter<EOT>::operator()(eo);
|
||||
// No need to increment value(), it is done in the superclass.
|
||||
|
||||
// increment t
|
||||
// if we have reached the maximum
|
||||
if ( value() >= _threshold ) {
|
||||
if ( this->value() >= _threshold ) {
|
||||
|
||||
// go back through the stack until catched
|
||||
throw eoMaxEvalException(_threshold);
|
||||
}
|
||||
|
||||
// evaluate
|
||||
this->eoEvalFuncCounter<EOT>::operator()(eo);
|
||||
|
||||
} // if invalid
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -92,12 +92,19 @@ public:
|
|||
*/
|
||||
std::vector<size_t> decode( const EOT& sol ) const
|
||||
{
|
||||
// Denormalize
|
||||
size_t cont = static_cast<size_t>(std::ceil( sol[i_cont] * _foundry.continuators.size() ));
|
||||
size_t cros = static_cast<size_t>(std::ceil( sol[i_cros] * _foundry.crossovers .size() ));
|
||||
size_t muta = static_cast<size_t>(std::ceil( sol[i_muta] * _foundry.mutations .size() ));
|
||||
size_t sele = static_cast<size_t>(std::ceil( sol[i_sele] * _foundry.selectors .size() ));
|
||||
size_t repl = static_cast<size_t>(std::ceil( sol[i_repl] * _foundry.replacements.size() ));
|
||||
// // Denormalize
|
||||
// size_t cont = static_cast<size_t>(std::ceil( sol[i_cont] * _foundry.continuators.size() ));
|
||||
// size_t cros = static_cast<size_t>(std::ceil( sol[i_cros] * _foundry.crossovers .size() ));
|
||||
// size_t muta = static_cast<size_t>(std::ceil( sol[i_muta] * _foundry.mutations .size() ));
|
||||
// size_t sele = static_cast<size_t>(std::ceil( sol[i_sele] * _foundry.selectors .size() ));
|
||||
// size_t repl = static_cast<size_t>(std::ceil( sol[i_repl] * _foundry.replacements.size() ));
|
||||
|
||||
// Direct encoding
|
||||
size_t cont = static_cast<size_t>(std::ceil( sol[i_cont] ));
|
||||
size_t cros = static_cast<size_t>(std::ceil( sol[i_cros] ));
|
||||
size_t muta = static_cast<size_t>(std::ceil( sol[i_muta] ));
|
||||
size_t sele = static_cast<size_t>(std::ceil( sol[i_sele] ));
|
||||
size_t repl = static_cast<size_t>(std::ceil( sol[i_repl] ));
|
||||
|
||||
return {cont, cros, muta, sele, repl};
|
||||
}
|
||||
|
|
|
|||
224
eo/src/eoEvalFoundryFastGA.h
Normal file
224
eo/src/eoEvalFoundryFastGA.h
Normal file
|
|
@ -0,0 +1,224 @@
|
|||
|
||||
/*
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation;
|
||||
version 2 of the License.
|
||||
|
||||
This library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
© 2020 Thales group
|
||||
|
||||
Authors:
|
||||
Johann Dreo <johann.dreo@thalesgroup.com>
|
||||
*/
|
||||
|
||||
#ifndef _eoEvalFoundryFastGA_H_
|
||||
#define _eoEvalFoundryFastGA_H_
|
||||
|
||||
#include "eoEvalFunc.h"
|
||||
#include "eoAlgoFoundryFastGA.h"
|
||||
#include "eoInit.h"
|
||||
#include "eoPopEvalFunc.h"
|
||||
|
||||
/** Evaluate an algorithm assembled by an eoAlgoFoundryFastGA, encoded as a numeric vector.
|
||||
*
|
||||
* Allows to plug another search algorithm on top of an eoAlgoFoundryFastGA,
|
||||
* so as to find the best configuration.
|
||||
*
|
||||
* The first template EOT is the encoding of the high-level algorithm selection problem,
|
||||
* the second template SUB is the encoding of the low-level generic problem.
|
||||
*
|
||||
* @ingroup Evaluation
|
||||
* @ingroup Foundry
|
||||
*/
|
||||
template<class EOT, class SUB>
|
||||
class eoEvalFoundryFastGA : public eoEvalFunc<EOT>
|
||||
{
|
||||
public:
|
||||
/** Takes the necessary parameters to perform a search on the sub-problem.
|
||||
*
|
||||
* @param foundry The set of algorithms among which to select.
|
||||
* @param subpb_init An initilizer for sub-problem encoding.
|
||||
* @param offspring_size Population size for the sub-problem solver.
|
||||
* @param subpb_eval The sub-problem itself.
|
||||
* @param penalization If any solution to the high-level algorithm selection problem is out of bounds, set it to this value.
|
||||
*/
|
||||
eoEvalFoundryFastGA(
|
||||
eoAlgoFoundryFastGA<SUB>& foundry,
|
||||
const size_t pop_size,
|
||||
eoInit<SUB>& subpb_init,
|
||||
eoPopEvalFunc<SUB>& subpb_eval,
|
||||
const typename SUB::Fitness penalization,
|
||||
const bool normalized = false
|
||||
) :
|
||||
_pop_size(pop_size),
|
||||
_subpb_init(subpb_init),
|
||||
_subpb_eval(subpb_eval),
|
||||
_foundry(foundry),
|
||||
_penalization(penalization),
|
||||
_normalized(normalized),
|
||||
i_crat(foundry.crossover_rates.index()),
|
||||
i_crsl(foundry.crossover_selectors.index()),
|
||||
i_cros(foundry.crossovers.index()),
|
||||
i_afcr(foundry.aftercross_selectors.index()),
|
||||
i_mrat(foundry.mutation_rates.index()),
|
||||
i_musl(foundry.mutation_selectors.index()),
|
||||
i_muta(foundry.mutations.index()),
|
||||
i_repl(foundry.replacements.index()),
|
||||
i_cont(foundry.continuators.index()),
|
||||
i_offs(foundry.offspring_sizes.index())
|
||||
{ }
|
||||
|
||||
protected:
|
||||
const size_t i_crat;
|
||||
const size_t i_crsl;
|
||||
const size_t i_cros;
|
||||
const size_t i_afcr;
|
||||
const size_t i_mrat;
|
||||
const size_t i_musl;
|
||||
const size_t i_muta;
|
||||
const size_t i_repl;
|
||||
const size_t i_cont;
|
||||
const size_t i_offs;
|
||||
|
||||
public:
|
||||
|
||||
/** Decode the high-level problem encoding as an array of indices.
|
||||
*
|
||||
* @note: If the EOT is an eoInt, this will be optimized out.
|
||||
*
|
||||
* May be useful for getting a solution back into an eoAlgoFoundryFastGA.
|
||||
* @code
|
||||
* foundry = eval.decode(pop.best_element());
|
||||
* std::cout << foundry.name() << std::endl;
|
||||
* auto& cont = foundry.continuator(); // Get the configured operator
|
||||
* @encode
|
||||
*/
|
||||
std::vector<size_t> decode( const EOT& sol ) const
|
||||
{
|
||||
size_t crat;
|
||||
size_t crsl;
|
||||
size_t cros;
|
||||
size_t afcr;
|
||||
size_t mrat;
|
||||
size_t musl;
|
||||
size_t muta;
|
||||
size_t repl;
|
||||
size_t cont;
|
||||
size_t offs;
|
||||
|
||||
if(_normalized) {
|
||||
crat = static_cast<size_t>(std::ceil( sol[i_crat] * _foundry.crossover_rates.size() ));
|
||||
crsl = static_cast<size_t>(std::ceil( sol[i_crsl] * _foundry.crossover_selectors.size() ));
|
||||
cros = static_cast<size_t>(std::ceil( sol[i_cros] * _foundry.crossovers.size() ));
|
||||
afcr = static_cast<size_t>(std::ceil( sol[i_afcr] * _foundry.aftercross_selectors.size() ));
|
||||
mrat = static_cast<size_t>(std::ceil( sol[i_mrat] * _foundry.mutation_rates.size() ));
|
||||
musl = static_cast<size_t>(std::ceil( sol[i_musl] * _foundry.mutation_selectors.size() ));
|
||||
muta = static_cast<size_t>(std::ceil( sol[i_muta] * _foundry.mutations.size() ));
|
||||
repl = static_cast<size_t>(std::ceil( sol[i_repl] * _foundry.replacements.size() ));
|
||||
cont = static_cast<size_t>(std::ceil( sol[i_cont] * _foundry.continuators.size() ));
|
||||
offs = static_cast<size_t>(std::ceil( sol[i_offs] * _foundry.offspring_sizes.size() ));
|
||||
|
||||
} else {
|
||||
crat = static_cast<size_t>(std::ceil( sol[i_crat] ));
|
||||
crsl = static_cast<size_t>(std::ceil( sol[i_crsl] ));
|
||||
cros = static_cast<size_t>(std::ceil( sol[i_cros] ));
|
||||
afcr = static_cast<size_t>(std::ceil( sol[i_afcr] ));
|
||||
mrat = static_cast<size_t>(std::ceil( sol[i_mrat] ));
|
||||
musl = static_cast<size_t>(std::ceil( sol[i_musl] ));
|
||||
muta = static_cast<size_t>(std::ceil( sol[i_muta] ));
|
||||
repl = static_cast<size_t>(std::ceil( sol[i_repl] ));
|
||||
cont = static_cast<size_t>(std::ceil( sol[i_cont] ));
|
||||
offs = static_cast<size_t>(std::ceil( sol[i_offs] ));
|
||||
}
|
||||
return {crat, crsl, cros, afcr, mrat, musl, muta, repl, cont, offs};
|
||||
}
|
||||
|
||||
/** Perform a sub-problem search with the configuration encoded in the given solution
|
||||
* and set its (high-level) fitness to the best (low-level) fitness found.
|
||||
*
|
||||
* You may want to overload this to perform multiple runs or solve multiple sub-problems.
|
||||
*/
|
||||
virtual void operator()(EOT& sol)
|
||||
{
|
||||
if(not sol.invalid()) {
|
||||
return;
|
||||
}
|
||||
auto config = decode(sol);
|
||||
double crat = config[i_crat];
|
||||
double crsl = config[i_crsl];
|
||||
double cros = config[i_cros];
|
||||
double afcr = config[i_afcr];
|
||||
double mrat = config[i_mrat];
|
||||
double musl = config[i_musl];
|
||||
double muta = config[i_muta];
|
||||
double repl = config[i_repl];
|
||||
double cont = config[i_cont];
|
||||
double offs = config[i_offs];
|
||||
|
||||
if(
|
||||
0 <= crat and crat < _foundry.crossover_rates.size()
|
||||
and 0 <= crsl and crsl < _foundry.crossover_selectors.size()
|
||||
and 0 <= cros and cros < _foundry.crossovers.size()
|
||||
and 0 <= afcr and afcr < _foundry.aftercross_selectors.size()
|
||||
and 0 <= mrat and mrat < _foundry.mutation_rates.size()
|
||||
and 0 <= musl and musl < _foundry.mutation_selectors.size()
|
||||
and 0 <= muta and muta < _foundry.mutations.size()
|
||||
and 0 <= repl and repl < _foundry.replacements.size()
|
||||
and 0 <= cont and cont < _foundry.continuators.size()
|
||||
and 0 <= offs and offs < _foundry.offspring_sizes.size()
|
||||
) {
|
||||
_foundry.select(config);
|
||||
|
||||
// Reset pop
|
||||
eoPop<SUB> pop;
|
||||
pop.append( _pop_size, _subpb_init);
|
||||
_subpb_eval(pop,pop);
|
||||
|
||||
// Actually perform a search
|
||||
_foundry(pop);
|
||||
|
||||
sol.fitness( pop.best_element().fitness() );
|
||||
|
||||
} else {
|
||||
eo::log << eo::warnings << "WARNING: encoded algo is out of bounds, penalize to: " << _penalization << std::endl;
|
||||
sol.fitness( _penalization ); // penalization
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
const size_t _pop_size;
|
||||
eoInit<SUB>& _subpb_init;
|
||||
eoPopEvalFunc<SUB>& _subpb_eval;
|
||||
eoAlgoFoundryFastGA<SUB>& _foundry;
|
||||
const typename EOT::Fitness _penalization;
|
||||
const bool _normalized;
|
||||
};
|
||||
|
||||
/** Helper function to instanciate an eoEvalFoundryFastGA without having to indicate the template for the sub-problem encoding.
|
||||
*
|
||||
* The template is deduced from the constructor's parameters.
|
||||
* Not sure it's more concise than a classical instanciation…
|
||||
*/
|
||||
template<class EOT, class SUB>
|
||||
eoEvalFoundryFastGA<EOT,SUB>&
|
||||
make_eoEvalFoundryFastGA(
|
||||
eoInit<SUB>& subpb_init,
|
||||
eoPopEvalFunc<SUB>& subpb_eval,
|
||||
eoAlgoFoundryFastGA<SUB>& foundry,
|
||||
const typename SUB::Fitness penalization,
|
||||
const bool normalized = false )
|
||||
{
|
||||
return *(new eoEvalFoundryFastGA<EOT,SUB>(subpb_init, subpb_eval, foundry, penalization, normalized));
|
||||
}
|
||||
|
||||
#endif // _eoEvalFoundryFastGA_H_
|
||||
|
||||
|
|
@ -45,8 +45,9 @@ template<class EOT> class eoEvalFuncCounter : public eoEvalFunc<EOT>, public eoV
|
|||
{
|
||||
if (_eo.invalid())
|
||||
{
|
||||
value()++;
|
||||
func(_eo);
|
||||
value()++;
|
||||
eo::log << eo::xdebug << "eoEvalFuncCounter: " << value() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
23
eo/src/eoEvalPrint.h
Normal file
23
eo/src/eoEvalPrint.h
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
|
||||
template< class EOT>
|
||||
class eoEvalPrint: public eoEvalFunc<EOT>
|
||||
{
|
||||
protected:
|
||||
std::ostream& _out;
|
||||
eoEvalFunc<EOT>& _eval;
|
||||
std::string _sep;
|
||||
|
||||
public:
|
||||
|
||||
eoEvalPrint(eoEvalFunc<EOT>& eval, std::ostream& out=std::cout, std::string sep="\n") :
|
||||
_out(out),
|
||||
_eval(eval),
|
||||
_sep(sep)
|
||||
{}
|
||||
|
||||
void operator()( EOT& sol )
|
||||
{
|
||||
_eval(sol);
|
||||
_out << sol << _sep;
|
||||
}
|
||||
};
|
||||
159
eo/src/eoFastGA.h
Normal file
159
eo/src/eoFastGA.h
Normal file
|
|
@ -0,0 +1,159 @@
|
|||
|
||||
/*
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation;
|
||||
version 2 of the License.
|
||||
|
||||
This library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _eoFastGA_H_
|
||||
#define _eoFastGA_H_
|
||||
|
||||
/** The Fast Genetic Algorithm.
|
||||
*
|
||||
* @ingroup Algorithms
|
||||
*/
|
||||
template<class EOT>
|
||||
class eoFastGA : public eoAlgo<EOT>
|
||||
{
|
||||
protected:
|
||||
double _rate_crossover;
|
||||
eoSelectOne<EOT>& _select_cross;
|
||||
eoQuadOp<EOT>& _crossover;
|
||||
eoSelectOne<EOT>& _select_aftercross;
|
||||
|
||||
double _rate_mutation;
|
||||
eoSelectOne<EOT>& _select_mut;
|
||||
eoMonOp<EOT>& _mutation;
|
||||
|
||||
eoPopEvalFunc<EOT>& _pop_eval;
|
||||
eoReplacement<EOT>& _replace;
|
||||
|
||||
eoContinue<EOT>& _continuator;
|
||||
|
||||
double _offsprings_size;
|
||||
|
||||
public:
|
||||
|
||||
eoFastGA(
|
||||
double rate_crossover,
|
||||
eoSelectOne<EOT>& select_cross,
|
||||
eoQuadOp<EOT>& crossover,
|
||||
eoSelectOne<EOT>& select_aftercross,
|
||||
double rate_mutation,
|
||||
eoSelectOne<EOT>& select_mut,
|
||||
eoMonOp<EOT>& mutation,
|
||||
eoPopEvalFunc<EOT>& pop_eval,
|
||||
eoReplacement<EOT>& replace,
|
||||
eoContinue<EOT>& continuator,
|
||||
double offsprings_size = 0
|
||||
) :
|
||||
_rate_crossover(rate_crossover),
|
||||
_select_cross(select_cross),
|
||||
_crossover(crossover),
|
||||
_select_aftercross(select_aftercross),
|
||||
_rate_mutation(rate_mutation),
|
||||
_select_mut(select_mut),
|
||||
_mutation(mutation),
|
||||
_pop_eval(pop_eval),
|
||||
_replace(replace),
|
||||
_continuator(continuator),
|
||||
_offsprings_size(offsprings_size)
|
||||
{
|
||||
}
|
||||
|
||||
void operator()(eoPop<EOT>& pop)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
assert(pop.size() > 0);
|
||||
for(auto sol : pop) {
|
||||
assert(not sol.invalid());
|
||||
}
|
||||
#endif
|
||||
// Set lambda to the pop size
|
||||
// if it was not set up at construction.
|
||||
if(_offsprings_size == 0) {
|
||||
// eo::log << eo::debug << "Set offspring size to: " << pop.size() << std::endl;
|
||||
_offsprings_size = pop.size();
|
||||
}
|
||||
|
||||
do {
|
||||
eoPop<EOT> offsprings;
|
||||
|
||||
for(size_t i=0; i < _offsprings_size; ++i) {
|
||||
// eo::log << eo::xdebug << "\tOffspring #" << i << std::endl;
|
||||
|
||||
if(eo::rng.flip(_rate_crossover)) {
|
||||
// eo::log << eo::xdebug << "\t\tDo crossover" << std::endl;
|
||||
// Manual setup of eoSelectOne
|
||||
// (usually they are setup in a
|
||||
// wrapping eoSelect).
|
||||
_select_cross.setup(pop);
|
||||
|
||||
// Copy of const ref solutions,
|
||||
// because one alter them hereafter.
|
||||
EOT sol1 = _select_cross(pop);
|
||||
EOT sol2 = _select_cross(pop);
|
||||
|
||||
// If the operator returns true,
|
||||
// solutions have been altered.
|
||||
if(_crossover(sol1, sol2)) {
|
||||
sol1.invalidate();
|
||||
sol2.invalidate();
|
||||
}
|
||||
|
||||
// Select one of the two solutions
|
||||
// which have been crossed.
|
||||
eoPop<EOT> crossed;
|
||||
crossed.push_back(sol1);
|
||||
crossed.push_back(sol2);
|
||||
_select_aftercross.setup(crossed);
|
||||
EOT sol3 = _select_aftercross(crossed);
|
||||
|
||||
// Additional mutation (X)OR the crossed/cloned solution.
|
||||
if(eo::rng.flip(_rate_mutation)) {
|
||||
// eo::log << eo::xdebug << "\t\tDo mutation" << std::endl;
|
||||
if(_mutation(sol3)) {
|
||||
sol3.invalidate();
|
||||
}
|
||||
}
|
||||
offsprings.push_back(sol3);
|
||||
|
||||
} else { // If not crossing, always mutate.
|
||||
// eo::log << eo::xdebug << "\t\tNo crossover, do mutation" << std::endl;
|
||||
_select_mut.setup(pop);
|
||||
EOT sol3 = _select_mut(pop);
|
||||
if(_mutation(sol3)) {
|
||||
sol3.invalidate();
|
||||
}
|
||||
offsprings.push_back(sol3);
|
||||
}
|
||||
}
|
||||
assert(offsprings.size() == _offsprings_size);
|
||||
|
||||
_pop_eval(pop, offsprings);
|
||||
_replace(pop, offsprings);
|
||||
|
||||
// eo::log << eo::xdebug << "\tEnd of generation" << std::endl;
|
||||
|
||||
} while(_continuator(pop));
|
||||
#ifndef NDEBUG
|
||||
assert(pop.size() > 0);
|
||||
for(auto sol : pop) {
|
||||
assert(not sol.invalid());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif // _eoFastGA_H_
|
||||
|
|
@ -36,7 +36,7 @@
|
|||
*
|
||||
* @ingroup Representations
|
||||
*/
|
||||
template <class FitT> class eoInt: public eoVector<FitT, int>
|
||||
template <class FitT, class T = size_t> class eoInt: public eoVector<FitT, T>
|
||||
{
|
||||
public:
|
||||
|
||||
|
|
@ -45,14 +45,14 @@ template <class FitT> class eoInt: public eoVector<FitT, int>
|
|||
* @param size Size of the std::vector
|
||||
* @param value fill the vector with this value
|
||||
*/
|
||||
eoInt(unsigned size = 0, int value = 0) :
|
||||
eoVector<FitT, int>(size, value)
|
||||
eoInt(unsigned size = 0, T value = 0) :
|
||||
eoVector<FitT, T>(size, value)
|
||||
{}
|
||||
|
||||
/** Constructor copying from a vector (or an initialization list).
|
||||
*/
|
||||
eoInt(std::vector<int> vec) :
|
||||
eoVector<FitT, int>(vec)
|
||||
eoInt(std::vector<T> vec) :
|
||||
eoVector<FitT, T>(vec)
|
||||
{}
|
||||
|
||||
/// My class name.
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
|
||||
#include "utils/eoRNG.h"
|
||||
#include "utils/selectors.h"
|
||||
#include "utils/eoLogger.h"
|
||||
#include "eoSelectOne.h"
|
||||
#include "eoPop.h"
|
||||
|
||||
|
|
@ -92,9 +93,9 @@ public:
|
|||
typename FitVec::iterator result
|
||||
= std::upper_bound(cumulative.begin(), cumulative.end(), fortune);
|
||||
|
||||
assert(fortune <= cumulative.back());
|
||||
// assert(fortune <= cumulative.back());
|
||||
|
||||
if(result - cumulative.begin() == _pop.size()) {
|
||||
if(result - cumulative.begin() >= _pop.size()) {
|
||||
return _pop.back();
|
||||
} else {
|
||||
return _pop[result - cumulative.begin()];
|
||||
|
|
|
|||
|
|
@ -48,6 +48,9 @@ template <class EOT> class eoRandomSelect: public eoSelectOne<EOT>
|
|||
{
|
||||
return _pop[eo::rng.random(_pop.size())] ;
|
||||
}
|
||||
|
||||
virtual std::string className() const {return "eoRandomSelect";}
|
||||
|
||||
};
|
||||
|
||||
/** eoBestSelect: a selection method that always return the best
|
||||
|
|
@ -64,6 +67,8 @@ template <class EOT> class eoBestSelect: public eoSelectOne<EOT>
|
|||
{
|
||||
return _pop.best_element() ;
|
||||
}
|
||||
|
||||
virtual std::string className() const {return "eoBestSelect";}
|
||||
};
|
||||
|
||||
/** eoNoSelect: returns all individual in order WITHOUT USING FITNESS!!!
|
||||
|
|
@ -86,6 +91,9 @@ template <class EOT> class eoNoSelect: public eoSelectOne<EOT>
|
|||
current++;
|
||||
return _pop[current-1] ;
|
||||
}
|
||||
|
||||
virtual std::string className() const {return "eoNoSelect";}
|
||||
|
||||
private:
|
||||
unsigned current;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -112,9 +112,14 @@ comparing with less is the default behaviour.
|
|||
// typedef eoScalarFitness<double, std::greater<double> > eoMinimizingFitness;
|
||||
// #endif
|
||||
|
||||
using eoMaximizingFitness = eoScalarFitness<double, std::less<double> >;
|
||||
using eoMinimizingFitness = eoScalarFitness<double, std::greater<double> >;
|
||||
template<class T=double>
|
||||
using eoMaximizingFitnessT = eoScalarFitness<T, std::less<T> >;
|
||||
|
||||
template<class T=double>
|
||||
using eoMinimizingFitnessT = eoScalarFitness<T, std::greater<T> >;
|
||||
|
||||
using eoMaximizingFitness = eoMaximizingFitnessT<double>;
|
||||
using eoMinimizingFitness = eoMinimizingFitnessT<double>;
|
||||
|
||||
template <class F, class Cmp>
|
||||
std::ostream& operator<<(std::ostream& os, const eoScalarFitness<F, Cmp>& f)
|
||||
|
|
|
|||
|
|
@ -110,10 +110,8 @@ class eoDetSingleBitFlip: public eoMonOp<Chrom>
|
|||
* (Default) Constructor.
|
||||
* @param _num_bit The number of bits to change
|
||||
* default is one - equivalent to eoOneBitFlip then
|
||||
*
|
||||
* @note: use a reference for num_bit, thus you may change and recall without having to re-instantiate.
|
||||
*/
|
||||
eoDetSingleBitFlip(const unsigned& _num_bit = 1): num_bit(_num_bit) {}
|
||||
eoDetSingleBitFlip(const unsigned _num_bit = 1): num_bit(_num_bit) {}
|
||||
|
||||
/// The class name.
|
||||
virtual std::string className() const { return "eoDetSingleBitFlip"; }
|
||||
|
|
@ -138,6 +136,7 @@ class eoDetSingleBitFlip: public eoMonOp<Chrom>
|
|||
}
|
||||
|
||||
// Flip at first indices
|
||||
assert(num_bit <= chrom.size());
|
||||
for(unsigned i=0; i<num_bit; ++i) {
|
||||
chrom[indices[i]] = !chrom[indices[i]];
|
||||
}
|
||||
|
|
@ -149,8 +148,13 @@ class eoDetSingleBitFlip: public eoMonOp<Chrom>
|
|||
}
|
||||
}
|
||||
|
||||
void number_bits(const unsigned _num_bit)
|
||||
{
|
||||
num_bit = _num_bit;
|
||||
}
|
||||
|
||||
protected:
|
||||
const unsigned& num_bit;
|
||||
unsigned num_bit;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@ class eoStandardBitMutation : public eoMonOp<EOT>
|
|||
return _bitflip(chrom);
|
||||
}
|
||||
|
||||
virtual std::string className() const {return "eoStandardBitMutation";}
|
||||
|
||||
protected:
|
||||
double _rate;
|
||||
unsigned _nb;
|
||||
|
|
@ -58,6 +60,8 @@ class eoUniformBitMutation : public eoMonOp<EOT>
|
|||
return _bitflip(chrom);
|
||||
}
|
||||
|
||||
virtual std::string className() const {return "eoUniformBitMutation";}
|
||||
|
||||
protected:
|
||||
double _rate;
|
||||
unsigned _nb;
|
||||
|
|
@ -93,6 +97,8 @@ class eoConditionalBitMutation : public eoStandardBitMutation<EOT>
|
|||
// thus one don't need to re-instantiate.
|
||||
return this->_bitflip(chrom);
|
||||
}
|
||||
|
||||
virtual std::string className() const {return "eoConditionalBitMutation";}
|
||||
};
|
||||
|
||||
/** Shifted standard bit mutation with mutation rate p:
|
||||
|
|
@ -125,6 +131,8 @@ class eoShiftedBitMutation : public eoStandardBitMutation<EOT>
|
|||
// thus one don't need to re-instantiate.
|
||||
return this->_bitflip(chrom);
|
||||
}
|
||||
|
||||
virtual std::string className() const {return "eoShiftedBitMutation";}
|
||||
};
|
||||
|
||||
/** Mutation which size is sample in a gaussian.
|
||||
|
|
@ -163,6 +171,8 @@ class eoNormalBitMutation : public eoStandardBitMutation<EOT>
|
|||
return this->_bitflip(chrom);
|
||||
}
|
||||
|
||||
virtual std::string className() const {return "eoNormalBitMutation";}
|
||||
|
||||
protected:
|
||||
double _variance;
|
||||
};
|
||||
|
|
@ -196,6 +206,8 @@ class eoFastBitMutation : public eoStandardBitMutation<EOT>
|
|||
return this->_bitflip(chrom);
|
||||
}
|
||||
|
||||
virtual std::string className() const {return "eoFastBitMutation";}
|
||||
|
||||
protected:
|
||||
|
||||
double powerlaw(unsigned n, double beta)
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ eoInit<EOT> & do_make_genotype(eoParser& _parser, eoState& _state, EOT, float _b
|
|||
|
||||
// Then we can built a bitstring random initializer
|
||||
// based on boolean_generator class (see utils/rnd_generator.h)
|
||||
eoBooleanGenerator * gen = new eoBooleanGenerator(_bias);
|
||||
eoBooleanGenerator<bool> * gen = new eoBooleanGenerator<bool>(_bias);
|
||||
_state.storeFunctor(gen);
|
||||
eoInitFixedLength<EOT>* init = new eoInitFixedLength<EOT>(theSize, *gen);
|
||||
// store in state
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@
|
|||
#include "eoGenCounter.h"
|
||||
|
||||
// and make_help - any better suggestion to include it?
|
||||
void make_help(eoParser & _parser, bool exit_after = true);
|
||||
void make_help(eoParser & _parser, bool exit_after = true, std::ostream& out = std::cout);
|
||||
|
||||
#endif // !_CHECKPOINTING_
|
||||
|
||||
|
|
|
|||
|
|
@ -115,15 +115,16 @@ inline bool eoUniformGenerator<bool>::operator()(void)
|
|||
to easily generate random booleans with a specified bias
|
||||
\ingroup bitstring
|
||||
*/
|
||||
class eoBooleanGenerator : public eoRndGenerator<bool>
|
||||
template<class T=bool>
|
||||
class eoBooleanGenerator : public eoRndGenerator<T>
|
||||
{
|
||||
public :
|
||||
eoBooleanGenerator(float _bias = 0.5, eoRng& _rng = rng) : bias(_bias), gen(_rng) {}
|
||||
public :
|
||||
eoBooleanGenerator(float _bias = 0.5, eoRng& _rng = rng) : bias(_bias), gen(_rng) {}
|
||||
|
||||
bool operator()(void) { return gen.flip(bias); }
|
||||
private :
|
||||
float bias;
|
||||
eoRng& gen;
|
||||
T operator()(void) { return gen.flip(bias); }
|
||||
private :
|
||||
float bias;
|
||||
eoRng& gen;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@
|
|||
* It is declared in all make_xxx.h files in representation-dependent dirs
|
||||
* but it is NOT representation-dependent itself - that's why it's in utils
|
||||
*/
|
||||
void make_help(eoParser & _parser, bool exit_after)
|
||||
void make_help(eoParser & _parser, bool exit_after, std::ostream& out)
|
||||
{
|
||||
// name of the "status" file where all actual parameter values will be saved
|
||||
std::string str_status = _parser.ProgramName() + ".status"; // default value
|
||||
|
|
@ -62,8 +62,8 @@ void make_help(eoParser & _parser, bool exit_after)
|
|||
// i.e. in case you need parameters somewhere else, postpone these
|
||||
if (_parser.userNeedsHelp())
|
||||
{
|
||||
_parser.printHelp(std::cout);
|
||||
std::cout << "You can use an edited copy of file " << statusParam.value()
|
||||
_parser.printHelp(out);
|
||||
out << "You can use an edited copy of file " << statusParam.value()
|
||||
<< " as parameter file" << std::endl;
|
||||
if(exit_after) {
|
||||
exit(0);
|
||||
|
|
|
|||
|
|
@ -76,7 +76,10 @@ set (TEST_LIST
|
|||
t-algo-forged
|
||||
t-algo-forged-search
|
||||
t-FastGA
|
||||
t-eoFastGA
|
||||
t-forge-FastGA
|
||||
t-eoFoundryFastGA
|
||||
t-eoAlgoFoundryFastGA
|
||||
)
|
||||
|
||||
|
||||
|
|
|
|||
79
eo/test/t-FastGA.cpp
Normal file
79
eo/test/t-FastGA.cpp
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
|
||||
/*
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation;
|
||||
version 2 of the License.
|
||||
|
||||
This library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
#include <eo>
|
||||
#include <ga.h>
|
||||
#include "../../problems/eval/oneMaxEval.h"
|
||||
|
||||
using EOT = eoBit<double>;
|
||||
|
||||
int main(int /*argc*/, char** /*argv*/)
|
||||
{
|
||||
size_t dim = 5;
|
||||
size_t pop_size = 3;
|
||||
|
||||
oneMaxEval<EOT> evalfunc;
|
||||
eoPopLoopEval<EOT> eval(evalfunc);
|
||||
|
||||
eoBooleanGenerator gen(0.5);
|
||||
eoInitFixedLength<EOT> init(dim, gen);
|
||||
|
||||
double cross_rate = 0.5;
|
||||
eoProportionalOp<EOT> cross;
|
||||
// Cross-over that produce only one offspring,
|
||||
// made by wrapping the quad op (which produce 2 offsprings)
|
||||
// in a bin op (which ignore the second offspring).
|
||||
eo1PtBitXover<EOT> crossover;
|
||||
eoQuad2BinOp<EOT> mono_cross(crossover);
|
||||
cross.add(mono_cross, cross_rate);
|
||||
eoBinCloneOp<EOT> bin_clone;
|
||||
cross.add(bin_clone, 1 - cross_rate); // Clone
|
||||
|
||||
double mut_rate = 0.5;
|
||||
eoProportionalOp<EOT> mut;
|
||||
eoShiftedBitMutation<EOT> mutation(0.5);
|
||||
mut.add(mutation, mut_rate);
|
||||
eoMonCloneOp<EOT> mon_clone;
|
||||
mut.add(mon_clone, 1 - mut_rate); // FIXME TBC
|
||||
|
||||
eoSequentialOp<EOT> variator;
|
||||
variator.add(cross,1.0);
|
||||
variator.add(mut,1.0);
|
||||
|
||||
double lambda = 1.0; // i.e. 100%
|
||||
eoStochTournamentSelect<EOT> selector(0.5);
|
||||
eoGeneralBreeder<EOT> breeder(selector, variator, lambda);
|
||||
|
||||
eoGenContinue<EOT> common_cont(3);
|
||||
eoCombinedContinue<EOT> gen_cont(common_cont);
|
||||
//gen_cont.add(continuator);
|
||||
|
||||
eoPlusReplacement<EOT> replacement;
|
||||
|
||||
eoEasyEA<EOT> algo = eoEasyEA<EOT>(gen_cont, eval, breeder, replacement);
|
||||
|
||||
eoPop<EOT> pop;
|
||||
pop.append(pop_size, init);
|
||||
eval(pop,pop);
|
||||
|
||||
algo(pop);
|
||||
|
||||
std::cout << pop.best_element() << std::endl;
|
||||
}
|
||||
147
eo/test/t-eoAlgoFoundryFastGA.cpp
Normal file
147
eo/test/t-eoAlgoFoundryFastGA.cpp
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
#include <eo>
|
||||
#include <ga.h>
|
||||
#include "../../problems/eval/oneMaxEval.h"
|
||||
|
||||
|
||||
int main(int /*argc*/, char** /*argv*/)
|
||||
{
|
||||
size_t dim = 500;
|
||||
size_t pop_size = 10;
|
||||
|
||||
eo::log << eo::setlevel(eo::warnings);
|
||||
|
||||
using EOT = eoBit<double>;
|
||||
|
||||
oneMaxEval<EOT> eval;
|
||||
|
||||
eoBooleanGenerator gen(0.5);
|
||||
eoInitFixedLength<EOT> init(dim, gen);
|
||||
|
||||
eoAlgoFoundryFastGA<EOT> foundry(init, eval, pop_size*10);
|
||||
|
||||
/***** Variation rates *****/
|
||||
for(double r = 0.0; r < 1.0; r+=0.1) {
|
||||
foundry.crossover_rates.add<double>(r);
|
||||
foundry. mutation_rates.add<double>(r);
|
||||
}
|
||||
|
||||
/***** Crossovers ****/
|
||||
foundry.crossovers.add< eo1PtBitXover<EOT> >();
|
||||
foundry.crossovers.add< eoUBitXover<EOT> >(0.5); // preference over 1
|
||||
for(size_t i=1; i < 11; i+=4) {
|
||||
foundry.crossovers.add< eoNPtsBitXover<EOT> >(i); // nb of points
|
||||
}
|
||||
|
||||
/***** Mutations ****/
|
||||
foundry.mutations.add< eoBitMutation<EOT> >(0.01); // proba of flipping one bit
|
||||
for(size_t i=1; i < 11; i+=4) {
|
||||
foundry.mutations.add< eoDetBitFlip<EOT> >(i); // mutate k bits
|
||||
}
|
||||
|
||||
/***** Selectors *****/
|
||||
for(eoOperatorFoundry<eoSelectOne<EOT>>& ops :
|
||||
{std::ref(foundry.crossover_selectors),
|
||||
std::ref(foundry.aftercross_selectors),
|
||||
std::ref(foundry.mutation_selectors) }) {
|
||||
|
||||
ops.add< eoRandomSelect<EOT> >();
|
||||
ops.add< eoStochTournamentSelect<EOT> >(0.5);
|
||||
ops.add< eoSequentialSelect<EOT> >();
|
||||
ops.add< eoProportionalSelect<EOT> >();
|
||||
for(size_t i=2; i < 10; i+=4) {
|
||||
ops.add< eoDetTournamentSelect<EOT> >(i);
|
||||
}
|
||||
}
|
||||
|
||||
/***** Replacements ****/
|
||||
foundry.replacements.add< eoCommaReplacement<EOT> >();
|
||||
foundry.replacements.add< eoPlusReplacement<EOT> >();
|
||||
foundry.replacements.add< eoSSGAWorseReplacement<EOT> >();
|
||||
foundry.replacements.add< eoSSGAStochTournamentReplacement<EOT> >(0.51);
|
||||
for(size_t i=2; i < 10; i+=4) {
|
||||
foundry.replacements.add< eoSSGADetTournamentReplacement<EOT> >(i);
|
||||
}
|
||||
|
||||
/***** Continuators ****/
|
||||
for(size_t i=10; i < 30; i+=10 ) {
|
||||
foundry.continuators.add< eoSteadyFitContinue<EOT> >(10,i);
|
||||
}
|
||||
|
||||
/***** Offspring population size *****/
|
||||
foundry.offspring_sizes.add<size_t>(0); // 0 = same as parent pop
|
||||
// for(size_t s = pop_size; s < 2*pop_size; s+=pop_size/10) {
|
||||
// foundry.offspring_sizes.add<size_t>(s);
|
||||
// }
|
||||
|
||||
|
||||
size_t n =
|
||||
foundry.crossover_rates.size()
|
||||
* foundry.crossover_selectors.size()
|
||||
* foundry.crossovers.size()
|
||||
* foundry.aftercross_selectors.size()
|
||||
* foundry.mutation_rates.size()
|
||||
* foundry.mutation_selectors.size()
|
||||
* foundry.mutations.size()
|
||||
* foundry.replacements.size()
|
||||
* foundry.continuators.size()
|
||||
* foundry.offspring_sizes.size();
|
||||
std::clog << n << " possible algorithms instances." << std::endl;
|
||||
|
||||
EOT best_sol;
|
||||
std::string best_algo = "";
|
||||
|
||||
size_t i=0;
|
||||
for(size_t i_crossrate = 0; i_crossrate < foundry.crossover_rates.size(); ++i_crossrate ) {
|
||||
for(size_t i_crossselect = 0; i_crossselect < foundry.crossover_selectors.size(); ++i_crossselect ) {
|
||||
for(size_t i_cross = 0; i_cross < foundry.crossovers.size(); ++i_cross ) {
|
||||
for(size_t i_aftercrosel = 0; i_aftercrosel < foundry.aftercross_selectors.size(); ++i_aftercrosel ) {
|
||||
for(size_t i_mutrate = 0; i_mutrate < foundry.mutation_rates.size(); ++i_mutrate ) {
|
||||
for(size_t i_mutselect = 0; i_mutselect < foundry.mutation_selectors.size(); ++i_mutselect ) {
|
||||
for(size_t i_mut = 0; i_mut < foundry.mutations.size(); ++i_mut ) {
|
||||
for(size_t i_rep = 0; i_rep < foundry.replacements.size(); ++i_rep ) {
|
||||
for(size_t i_cont = 0; i_cont < foundry.continuators.size(); ++i_cont ) {
|
||||
for(size_t i_pop = 0; i_pop < foundry.offspring_sizes.size(); ++i_pop ) {
|
||||
std::clog << "\r" << i++ << "/" << n-1; std::clog.flush();
|
||||
|
||||
eoPop<EOT> pop;
|
||||
pop.append(pop_size, init);
|
||||
|
||||
foundry.select({
|
||||
i_crossrate,
|
||||
i_crossselect,
|
||||
i_cross,
|
||||
i_aftercrosel,
|
||||
i_mutrate,
|
||||
i_mutselect,
|
||||
i_mut,
|
||||
i_rep,
|
||||
i_cont,
|
||||
i_pop
|
||||
});
|
||||
|
||||
// Actually perform a search
|
||||
foundry(pop);
|
||||
|
||||
if(best_sol.invalid()) {
|
||||
best_sol = pop.best_element();
|
||||
best_algo = foundry.name();
|
||||
} else if(pop.best_element().fitness() > best_sol.fitness()) {
|
||||
best_sol = pop.best_element();
|
||||
best_algo = foundry.name();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
std::cout << std::endl << "Best algo: " << best_algo << ", with " << best_sol << std::endl;
|
||||
|
||||
}
|
||||
72
eo/test/t-eoFastGA.cpp
Normal file
72
eo/test/t-eoFastGA.cpp
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
|
||||
/*
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation;
|
||||
version 2 of the License.
|
||||
|
||||
This library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
#include <eo>
|
||||
#include <ga.h>
|
||||
#include "../../problems/eval/oneMaxEval.h"
|
||||
|
||||
using EOT = eoBit<double>;
|
||||
|
||||
int main(int /*argc*/, char** /*argv*/)
|
||||
{
|
||||
size_t dim = 100;
|
||||
size_t pop_size = 10;
|
||||
|
||||
oneMaxEval<EOT> evalfunc;
|
||||
eoPopLoopEval<EOT> eval(evalfunc);
|
||||
|
||||
eoBooleanGenerator gen(0.5);
|
||||
eoInitFixedLength<EOT> init(dim, gen);
|
||||
|
||||
double cross_rate = 0.5;
|
||||
eoSequentialSelect<EOT> select_cross;
|
||||
eoUBitXover<EOT> crossover;
|
||||
eoRandomSelect<EOT> select_aftercross;
|
||||
|
||||
double mut_rate = 0.5;
|
||||
eoSequentialSelect<EOT> select_mut;
|
||||
eoStandardBitMutation<EOT> mutation(0.5);
|
||||
|
||||
eoPlusReplacement<EOT> replacement;
|
||||
|
||||
eoGenContinue<EOT> common_cont(dim*2);
|
||||
eoCombinedContinue<EOT> gen_cont(common_cont);
|
||||
|
||||
eoFastGA<EOT> algo(
|
||||
cross_rate,
|
||||
select_cross,
|
||||
crossover,
|
||||
select_aftercross,
|
||||
mut_rate,
|
||||
select_mut,
|
||||
mutation,
|
||||
eval,
|
||||
replacement,
|
||||
common_cont
|
||||
);
|
||||
|
||||
eoPop<EOT> pop;
|
||||
pop.append(pop_size, init);
|
||||
eval(pop,pop);
|
||||
|
||||
algo(pop);
|
||||
|
||||
std::cout << pop.best_element() << std::endl;
|
||||
}
|
||||
|
|
@ -26,7 +26,7 @@ eoAlgoFoundryFastGA<Bits>& make_foundry(eoFunctorStore& store, eoInit<Bits>& ini
|
|||
}
|
||||
|
||||
for(size_t i=5; i<100; i+=10) {
|
||||
foundry.pop_sizes.add<size_t>(i);
|
||||
foundry.offspring_sizes.add<size_t>(i);
|
||||
}
|
||||
|
||||
/***** Crossovers ****/
|
||||
|
|
@ -51,14 +51,24 @@ eoAlgoFoundryFastGA<Bits>& make_foundry(eoFunctorStore& store, eoInit<Bits>& ini
|
|||
}
|
||||
|
||||
/***** Selectors *****/
|
||||
foundry.selectors.add< eoRandomSelect<Bits> >();
|
||||
foundry.selectors.add< eoSequentialSelect<Bits> >();
|
||||
foundry.selectors.add< eoProportionalSelect<Bits> >();
|
||||
for(size_t i=2; i < 10; i+=1) { // Tournament size.
|
||||
foundry.selectors.add< eoDetTournamentSelect<Bits> >(i);
|
||||
for(eoOperatorFoundry<eoSelectOne<Bits>>& ops :
|
||||
{std::ref(foundry.crossover_selectors),
|
||||
std::ref(foundry.aftercross_selectors),
|
||||
std::ref(foundry.mutation_selectors) }) {
|
||||
|
||||
ops.add< eoRandomSelect<Bits> >();
|
||||
ops.add< eoStochTournamentSelect<Bits> >(0.5);
|
||||
ops.add< eoSequentialSelect<Bits> >();
|
||||
ops.add< eoProportionalSelect<Bits> >();
|
||||
for(size_t i=2; i < 10; i+=4) {
|
||||
ops.add< eoDetTournamentSelect<Bits> >(i);
|
||||
}
|
||||
}
|
||||
for(double i=0.51; i<0.91; i+=0.1) { // Tournament size as perc of pop.
|
||||
foundry.selectors.add< eoStochTournamentSelect<Bits> >(i);
|
||||
|
||||
/***** Variation rates *****/
|
||||
for(double r = 0.0; r < 1.0; r+=0.1) {
|
||||
foundry.crossover_rates.add<double>(r);
|
||||
foundry. mutation_rates.add<double>(r);
|
||||
}
|
||||
|
||||
/***** Replacements ****/
|
||||
|
|
@ -88,8 +98,20 @@ int main(int /*argc*/, char** /*argv*/)
|
|||
|
||||
auto& foundry = make_foundry(store, init, onemax_eval);
|
||||
|
||||
size_t n = foundry.continuators.size() * foundry.crossovers.size() * foundry.mutations.size() * foundry.selectors.size() * foundry.replacements.size()* foundry.crossover_rates.size() * foundry.mutation_rates.size() * foundry.pop_sizes.size();
|
||||
std::clog << n << " possible algorithms instances." << std::endl;
|
||||
|
||||
size_t n =
|
||||
foundry.crossover_rates.size()
|
||||
* foundry.crossover_selectors.size()
|
||||
* foundry.crossovers.size()
|
||||
* foundry.aftercross_selectors.size()
|
||||
* foundry.mutation_rates.size()
|
||||
* foundry.mutation_selectors.size()
|
||||
* foundry.mutations.size()
|
||||
* foundry.replacements.size()
|
||||
* foundry.continuators.size()
|
||||
* foundry.offspring_sizes.size();
|
||||
|
||||
std::clog << n << " possible algorithms instances." << std::endl;
|
||||
|
||||
eoPop<Bits> pop;
|
||||
pop.append(5,init);
|
||||
|
|
|
|||
115
eo/test/t-forge-FastGA.cpp
Normal file
115
eo/test/t-forge-FastGA.cpp
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
#include <eo>
|
||||
#include <ga.h>
|
||||
#include "../../problems/eval/oneMaxEval.h"
|
||||
|
||||
int main(int /*argc*/, char** /*argv*/)
|
||||
{
|
||||
size_t dim = 500;
|
||||
size_t pop_size = 10;
|
||||
|
||||
eo::log << eo::setlevel(eo::warnings);
|
||||
|
||||
using EOT = eoBit<double>;
|
||||
|
||||
oneMaxEval<EOT> eval;
|
||||
|
||||
eoBooleanGenerator gen(0.5);
|
||||
eoInitFixedLength<EOT> init(dim, gen);
|
||||
|
||||
eoGenContinue<EOT> common_cont(100);
|
||||
|
||||
eoForgeVector< eoContinue<EOT> > continuators;
|
||||
continuators.add< eoSteadyFitContinue<EOT> >(10,10);
|
||||
continuators.add< eoGenContinue<EOT> >(100);
|
||||
|
||||
eoForgeVector< eoQuadOp<EOT> > crossovers;
|
||||
crossovers.add< eo1PtBitXover<EOT> >();
|
||||
crossovers.add< eoUBitXover<EOT> >(0.5); // preference over 1
|
||||
crossovers.add< eoNPtsBitXover<EOT> >(2); // nb of points
|
||||
|
||||
eoForgeVector< eoMonOp<EOT> > mutations;
|
||||
mutations.add< eoBitMutation<EOT> >(0.01); // proba of flipping one bit
|
||||
mutations.add< eoDetBitFlip<EOT> >(1); // mutate k bits
|
||||
|
||||
eoForgeVector< eoSelectOne<EOT> > selectors;
|
||||
selectors.add< eoDetTournamentSelect<EOT> >(pop_size/2);
|
||||
selectors.add< eoStochTournamentSelect<EOT> >(0.5);
|
||||
selectors.add< eoSequentialSelect<EOT> >();
|
||||
selectors.add< eoProportionalSelect<EOT> >();
|
||||
|
||||
eoForgeVector< eoReplacement<EOT> > replacors;
|
||||
replacors.add< eoCommaReplacement<EOT> >();
|
||||
replacors.add< eoPlusReplacement<EOT> >();
|
||||
replacors.add< eoSSGAWorseReplacement<EOT> >();
|
||||
replacors.add< eoSSGADetTournamentReplacement<EOT> >(pop_size/2);
|
||||
replacors.add< eoSSGAStochTournamentReplacement<EOT> >(0.51);
|
||||
|
||||
std::clog << continuators.size() * crossovers.size() * mutations.size() * selectors.size() * replacors.size()
|
||||
<< " possible algorithms instances." << std::endl;
|
||||
|
||||
EOT best_sol;
|
||||
std::string best_algo = "";
|
||||
|
||||
for(auto& forge_cont : continuators) {
|
||||
auto& continuator = forge_cont->instantiate();
|
||||
|
||||
for(auto& forge_cross : crossovers) {
|
||||
auto& crossover = forge_cross->instantiate();
|
||||
|
||||
for(auto& forge_mut : mutations ) {
|
||||
auto& mutation = forge_mut->instantiate();
|
||||
|
||||
for(auto& forge_sel : selectors) {
|
||||
auto& selector = forge_sel->instantiate();
|
||||
|
||||
for(auto& forge_rep : replacors) {
|
||||
auto& replacor = forge_rep->instantiate();
|
||||
|
||||
std::ostringstream algo_name;
|
||||
algo_name << continuator.className() << " + "
|
||||
<< crossover.className() << " + "
|
||||
<< mutation.className() << " + "
|
||||
<< selector.className() << " + "
|
||||
<< replacor.className();
|
||||
|
||||
std::clog << "ALGO: " << algo_name.str();
|
||||
std::clog.flush();
|
||||
|
||||
eoSequentialOp<EOT> variator;
|
||||
variator.add(crossover, 1.0);
|
||||
variator.add(mutation, 1.0);
|
||||
|
||||
eoGeneralBreeder<EOT> breeder(selector, variator, 1.0);
|
||||
|
||||
eoCombinedContinue<EOT> gen_cont(common_cont);
|
||||
gen_cont.add(continuator);
|
||||
|
||||
eoEasyEA<EOT> algo(gen_cont, eval, breeder, replacor);
|
||||
|
||||
eoPop<EOT> pop;
|
||||
pop.append(pop_size, init);
|
||||
::apply(eval,pop);
|
||||
|
||||
algo(pop);
|
||||
|
||||
std::clog << " = " << pop.best_element().fitness() << std::endl;
|
||||
|
||||
if(best_sol.invalid()) {
|
||||
best_sol = pop.best_element();
|
||||
best_algo = algo_name.str();
|
||||
} else if(pop.best_element().fitness() > best_sol.fitness()) {
|
||||
best_sol = pop.best_element();
|
||||
best_algo = algo_name.str();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
std::cout << "Best algo: " << best_algo << ", with " << best_sol << std::endl;
|
||||
|
||||
}
|
||||
|
|
@ -200,7 +200,7 @@ class eoEvalIOHsuiteSingleDim : public eoEvalFunc<EOT>
|
|||
// Evaluate the performance of the encoded algo instance
|
||||
// on a whole IOH suite benchmark.
|
||||
typename IOHprofiler_suite<ScalarType>::Problem_ptr pb;
|
||||
while(pb = _ioh_suite->get_next_problem()) {
|
||||
while( (pb = _ioh_suite->get_next_problem()) ) {
|
||||
|
||||
// Consider a new problem.
|
||||
_eval.problem(*pb); // Will call logger's target_problem.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue