diff --git a/CMakeLists.txt b/CMakeLists.txt index f16c156..34b113b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.25) -project(blt-gp VERSION 0.1.53) +project(blt-gp VERSION 0.1.54) include(CTest) diff --git a/include/blt/gp/transformers.h b/include/blt/gp/transformers.h index af0b0a8..94ea7c7 100644 --- a/include/blt/gp/transformers.h +++ b/include/blt/gp/transformers.h @@ -85,10 +85,11 @@ namespace blt::gp std::optional get_crossover_point(gp_program& program, const tree_t& c1, const tree_t& c2) const; - std::optional get_point_traverse(gp_program& program, const tree_t& t, std::optional type, - bool scale_per_depth = true) const; + std::optional get_crossover_point_traverse(gp_program& program, const tree_t& c1, const tree_t& c2) const; - static std::optional find_place_of_type(gp_program& program, const tree_t& t, type_id type); + static std::optional get_point_traverse(gp_program& program, const tree_t& t, std::optional type); + + static std::optional random_place_of_type(gp_program& program, const tree_t& t, type_id type); /** * child1 and child2 are copies of the parents, the result of selecting a crossover point and performing standard subtree crossover. @@ -103,6 +104,8 @@ namespace blt::gp virtual ~crossover_t() = default; protected: + std::optional get_point_traverse_retry(gp_program& program, const tree_t& t, std::optional type) const; + config_t config; }; diff --git a/include/blt/gp/tree.h b/include/blt/gp/tree.h index dacffe0..7e3e0e2 100644 --- a/include/blt/gp/tree.h +++ b/include/blt/gp/tree.h @@ -158,6 +158,7 @@ namespace blt::gp void find_child_extends(gp_program& program, tracked_vector& vec, blt::size_t parent_node, blt::size_t argc) const; + // places one past the end of the child. so it's [start, end) blt::ptrdiff_t find_endpoint(blt::gp::gp_program& program, blt::ptrdiff_t start) const; blt::ptrdiff_t find_parent(blt::gp::gp_program& program, blt::ptrdiff_t start) const; diff --git a/lib/blt b/lib/blt index cd9ec50..0869509 160000 --- a/lib/blt +++ b/lib/blt @@ -1 +1 @@ -Subproject commit cd9ec507d63d5e45f36dd16665f2033b0b5fe5f2 +Subproject commit 0869509c6a5fd530efbd57469d2b99b89c22b769 diff --git a/src/transformers.cpp b/src/transformers.cpp index 71a1252..cd66400 100644 --- a/src/transformers.cpp +++ b/src/transformers.cpp @@ -211,7 +211,15 @@ namespace blt::gp return crossover_point_t{static_cast(crossover_point), static_cast(attempted_point)}; } - std::optional crossover_t::find_place_of_type(gp_program& program, const tree_t& t, type_id type) + 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, {}); + + return std::optional(); + } + + std::optional crossover_t::random_place_of_type(gp_program& program, const tree_t& t, type_id type) { 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); @@ -220,26 +228,50 @@ namespace blt::gp return {}; } - std::optional crossover_t::get_point_traverse(gp_program& program, const tree_t& t, std::optional type, - bool scale_per_depth) const + std::optional crossover_t::get_point_traverse(gp_program& program, const tree_t& t, std::optional type) { auto& random = program.get_random(); blt::ptrdiff_t point = 0; while (true) { + auto& current_op_type = program.get_operator_info(t.get_operations()[point].id); + if (current_op_type.argc.is_terminal()) + { + if (type && *type != current_op_type.return_type) + return {}; + return {{point, current_op_type}}; + } // traverse to a child if (random.choice()) { - - } - if (type) - { - + auto args = current_op_type.argc.argc; + auto argument = random.get_size_t(0, args); + + // move to the first child + point += 1; + // loop through all the children we wish to skip. The result will be the first node of the next child, becoming the new parent + for (blt::size_t i = 0; i < argument; i++) + point += t.find_endpoint(program, point); + + continue; } + if (type && *type == current_op_type.return_type) + return {{point, current_op_type}}; } } + std::optional crossover_t::get_point_traverse_retry(gp_program& program, const tree_t& t, + std::optional type) const + { + for (blt::size_t i = 0; i < config.max_crossover_tries; i++) + { + if (auto found = get_point_traverse(program, t, type)) + return found; + } + return {}; + } + bool mutation_t::apply(gp_program& program, const tree_t&, tree_t& c) { mutate_point(program, c, program.get_random().get_size_t(0ul, c.get_operations().size()));