diff --git a/CMakeLists.txt b/CMakeLists.txt index 34b113b..2300a71 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.25) -project(blt-gp VERSION 0.1.54) +project(blt-gp VERSION 0.1.55) include(CTest) diff --git a/include/blt/gp/transformers.h b/include/blt/gp/transformers.h index 94ea7c7..dc927de 100644 --- a/include/blt/gp/transformers.h +++ b/include/blt/gp/transformers.h @@ -61,7 +61,7 @@ namespace blt::gp struct point_info_t { type_id return_type; - operator_info_t& type_operator_info; + operator_info_t* type_operator_info; }; struct crossover_point_t { @@ -72,6 +72,10 @@ namespace blt::gp { // number of times crossover will try to pick a valid point in the tree. this is purely based on the return type of the operators blt::u16 max_crossover_tries = 5; + blt::f32 traverse_chance = 0.75; + + // legacy settings: + // if we fail to find a point in the tree, should we search forward from the last point to the end of the operators? bool should_crossover_try_forward = false; // avoid selecting terminals when doing crossover @@ -87,7 +91,7 @@ namespace blt::gp std::optional get_crossover_point_traverse(gp_program& program, const tree_t& c1, const tree_t& c2) const; - static std::optional get_point_traverse(gp_program& program, const tree_t& t, std::optional type); + std::optional get_point_traverse(gp_program& program, const tree_t& t, std::optional type) const; static std::optional random_place_of_type(gp_program& program, const tree_t& t, type_id type); diff --git a/src/transformers.cpp b/src/transformers.cpp index cd66400..0a6b213 100644 --- a/src/transformers.cpp +++ b/src/transformers.cpp @@ -214,9 +214,16 @@ namespace blt::gp std::optional crossover_t::get_crossover_point_traverse(gp_program& program, const tree_t& c1, const tree_t& c2) const { -// crossover_t::point_info_t c1_point = get_point_traverse_retry(program, c1, {}); + crossover_t::point_info_t c1_point{}; + crossover_t::point_info_t c2_point{}; - return std::optional(); + if (auto point = get_point_traverse_retry(program, c1, {})) + c1_point = *point; + else + return {}; + + + return {}; } std::optional crossover_t::random_place_of_type(gp_program& program, const tree_t& t, type_id type) @@ -224,11 +231,11 @@ namespace blt::gp auto attempted_point = program.get_random().get_size_t(1ul, t.get_operations().size()); auto& attempted_point_type = program.get_operator_info(t.get_operations()[attempted_point].id); if (type == attempted_point_type.return_type) - return {{attempted_point, attempted_point_type}}; + return {{attempted_point, &attempted_point_type}}; return {}; } - std::optional crossover_t::get_point_traverse(gp_program& program, const tree_t& t, std::optional type) + std::optional crossover_t::get_point_traverse(gp_program& program, const tree_t& t, std::optional type) const { auto& random = program.get_random(); @@ -240,10 +247,10 @@ namespace blt::gp { if (type && *type != current_op_type.return_type) return {}; - return {{point, current_op_type}}; + return {{point, ¤t_op_type}}; } // traverse to a child - if (random.choice()) + if (random.choice(config.traverse_chance)) { auto args = current_op_type.argc.argc; auto argument = random.get_size_t(0, args); @@ -256,8 +263,8 @@ namespace blt::gp continue; } - if (type && *type == current_op_type.return_type) - return {{point, current_op_type}}; + if (!type || (type && *type == current_op_type.return_type)) + return {{point, ¤t_op_type}}; } }