change default function to be more in line with koza's description of a gp

thread
Brett 2024-07-15 18:18:13 -04:00
parent 2081dd3e5f
commit 34a3343a89
3 changed files with 47 additions and 39 deletions

View File

@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.25) cmake_minimum_required(VERSION 3.25)
project(blt-gp VERSION 0.0.80) project(blt-gp VERSION 0.0.81)
include(CTest) include(CTest)

View File

@ -283,7 +283,7 @@ namespace blt::gp
* NOTE: 0 is considered the best, in terms of standardized fitness * NOTE: 0 is considered the best, in terms of standardized fitness
*/ */
template<typename FitnessFunc> template<typename FitnessFunc>
void generate_population(type_id root_type, FitnessFunc& fitness_function) void generate_population(type_id root_type, FitnessFunc& fitness_function, bool eval_fitness_now = true)
{ {
current_pop = config.pop_initializer.get().generate( current_pop = config.pop_initializer.get().generate(
{*this, root_type, config.population_size, config.initial_min_tree_size, config.initial_max_tree_size}); {*this, root_type, config.population_size, config.initial_min_tree_size, config.initial_max_tree_size});
@ -351,7 +351,8 @@ namespace blt::gp
}); });
thread_helper.thread_function_condition.notify_all(); thread_helper.thread_function_condition.notify_all();
} }
evaluate_fitness_internal(); if (eval_fitness_now)
evaluate_fitness_internal();
} }
void next_generation() void next_generation()

View File

@ -52,7 +52,7 @@ namespace blt::gp
{ {
for (blt::size_t i = 0; i < config.elites; i++) for (blt::size_t i = 0; i < config.elites; i++)
{ {
// BLT_INFO("%lf >= %lf? // %lf", ind.second.fitness.adjusted_fitness, values[i].second, ind.second.fitness.raw_fitness); //BLT_INFO("%lf >= %lf? // %lf", ind.second.fitness.adjusted_fitness, values[i].second, ind.second.fitness.raw_fitness);
if (ind.second.fitness.adjusted_fitness >= values[i].second) if (ind.second.fitness.adjusted_fitness >= values[i].second)
{ {
bool doesnt_contain = true; bool doesnt_contain = true;
@ -74,7 +74,7 @@ namespace blt::gp
}; };
template<typename Crossover, typename Mutation, typename Reproduction> template<typename Crossover, typename Mutation, typename Reproduction>
constexpr inline auto default_next_pop_creator = []( constexpr inline auto proportionate_next_pop_creator = [](
const selector_args& args, Crossover crossover_selection, Mutation mutation_selection, Reproduction reproduction_selection) { const selector_args& args, Crossover crossover_selection, Mutation mutation_selection, Reproduction reproduction_selection) {
auto& [program, next_pop, current_pop, current_stats, config, random] = args; auto& [program, next_pop, current_pop, current_stats, config, random] = args;
@ -132,7 +132,7 @@ namespace blt::gp
}; };
template<typename Crossover, typename Mutation, typename Reproduction> template<typename Crossover, typename Mutation, typename Reproduction>
constexpr inline auto non_deterministic_next_pop_creator = []( constexpr inline auto default_next_pop_creator = [](
const blt::gp::selector_args& args, Crossover crossover_selection, Mutation mutation_selection, Reproduction reproduction_selection) { const blt::gp::selector_args& args, Crossover crossover_selection, Mutation mutation_selection, Reproduction reproduction_selection) {
auto& [program, next_pop, current_pop, current_stats, config, random] = args; auto& [program, next_pop, current_pop, current_stats, config, random] = args;
@ -140,39 +140,46 @@ namespace blt::gp
while (next_pop.get_individuals().size() < config.population_size) while (next_pop.get_individuals().size() < config.population_size)
{ {
// everyone gets a chance once per loop. int sel = random.get_i32(0, 3);
if (random.choice(config.crossover_chance)) switch (sel){
{ case 0:
// crossover // everyone gets a chance once per loop.
auto& p1 = crossover_selection.select(program, current_pop, current_stats); if (random.choice(config.crossover_chance))
auto& p2 = crossover_selection.select(program, current_pop, current_stats); {
// crossover
auto& p1 = crossover_selection.select(program, current_pop, current_stats);
auto& p2 = crossover_selection.select(program, current_pop, current_stats);
auto results = config.crossover.get().apply(program, p1, p2); auto results = config.crossover.get().apply(program, p1, p2);
// if crossover fails, we can check for mutation on these guys. otherwise straight copy them into the next pop // if crossover fails, we can check for mutation on these guys. otherwise straight copy them into the next pop
if (results) if (results)
{ {
next_pop.get_individuals().emplace_back(std::move(results->child1)); next_pop.get_individuals().emplace_back(std::move(results->child1));
// annoying check // annoying check
if (next_pop.get_individuals().size() < config.population_size) if (next_pop.get_individuals().size() < config.population_size)
next_pop.get_individuals().emplace_back(std::move(results->child2)); next_pop.get_individuals().emplace_back(std::move(results->child2));
} }
} }
if (next_pop.get_individuals().size() >= config.population_size) break;
break; case 1:
if (random.choice(config.mutation_chance)) if (random.choice(config.mutation_chance))
{ {
// mutation // mutation
auto& p = mutation_selection.select(program, current_pop, current_stats); auto& p = mutation_selection.select(program, current_pop, current_stats);
next_pop.get_individuals().emplace_back(std::move(config.mutator.get().apply(program, p))); next_pop.get_individuals().emplace_back(std::move(config.mutator.get().apply(program, p)));
} }
if (next_pop.get_individuals().size() >= config.population_size) break;
break; case 2:
if (config.reproduction_chance > 0 && random.choice(config.reproduction_chance)) if (config.reproduction_chance > 0 && random.choice(config.reproduction_chance))
{ {
// reproduction // reproduction
auto& p = reproduction_selection.select(program, current_pop, current_stats); auto& p = reproduction_selection.select(program, current_pop, current_stats);
next_pop.get_individuals().push_back(individual{p}); next_pop.get_individuals().push_back(individual{p});
}
break;
default:
BLT_ABORT("This is not possible!");
} }
} }
}; };