change default function to be more in line with koza's description of a gp
parent
2081dd3e5f
commit
34a3343a89
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue