diff --git a/CMakeLists.txt b/CMakeLists.txt index 5eeae87..521bbd1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.25) -project(blt-gp VERSION 0.0.91) +project(blt-gp VERSION 0.0.92) include(CTest) diff --git a/include/blt/gp/transformers.h b/include/blt/gp/transformers.h index f846ad3..e418e73 100644 --- a/include/blt/gp/transformers.h +++ b/include/blt/gp/transformers.h @@ -27,11 +27,20 @@ namespace blt::gp { + namespace detail + { + using op_iter = std::vector::iterator; + } + + blt::ptrdiff_t find_endpoint(blt::gp::gp_program& program, const std::vector& container, blt::ptrdiff_t start); + + void transfer_forward(blt::gp::stack_allocator& from, blt::gp::stack_allocator& to, detail::op_iter begin, detail::op_iter end); + + void transfer_backward(blt::gp::stack_allocator& from, blt::gp::stack_allocator& to, detail::op_iter begin, detail::op_iter end); class crossover_t { public: - using op_iter = std::vector::iterator; enum class error_t { NO_VALID_TYPE, @@ -64,12 +73,6 @@ namespace blt::gp blt::expected get_crossover_point(gp_program& program, const tree_t& c1, const tree_t& c2) const; - static blt::ptrdiff_t find_endpoint(blt::gp::gp_program& program, const std::vector& container, - blt::ptrdiff_t start); - - static void transfer_forward(blt::gp::stack_allocator& from, blt::gp::stack_allocator& to, op_iter begin, op_iter end); - static void transfer_backward(blt::gp::stack_allocator& from, blt::gp::stack_allocator& to, op_iter begin, op_iter end); - /** * child1 and child2 are copies of the parents, the result of selecting a crossover point and performing standard subtree crossover. * the parents are not modified during this process diff --git a/lib/blt b/lib/blt index 60f7796..cd5c98d 160000 --- a/lib/blt +++ b/lib/blt @@ -1 +1 @@ -Subproject commit 60f77961fbbd4a1a06adbef984d838c5b49b3718 +Subproject commit cd5c98d748be0ceb7011fd0aaf0eec8140d97cc6 diff --git a/src/transformers.cpp b/src/transformers.cpp index 0819b36..f9f83a2 100644 --- a/src/transformers.cpp +++ b/src/transformers.cpp @@ -51,12 +51,13 @@ namespace blt::gp stack_allocator& c1_stack_init = c1.get_values(); stack_allocator& c2_stack_init = c2.get_values(); + // we have to make a copy because we will modify the underlying storage. std::vector c1_operators; std::vector c2_operators; - for (const auto& op : blt::enumerate(crossover_point_begin_itr, crossover_point_end_itr)) + for (const auto& op : blt::iterate(crossover_point_begin_itr, crossover_point_end_itr)) c1_operators.push_back(op); - for (const auto& op : blt::enumerate(found_point_begin_itr, found_point_end_itr)) + for (const auto& op : blt::iterate(found_point_begin_itr, found_point_end_itr)) c2_operators.push_back(op); stack_allocator c1_stack_after_copy; @@ -149,43 +150,6 @@ namespace blt::gp return crossover_point_t{static_cast(crossover_point), static_cast(attempted_point)}; } - blt::ptrdiff_t crossover_t::find_endpoint(blt::gp::gp_program& program, const std::vector& container, blt::ptrdiff_t index) - { - blt::i64 children_left = 0; - - do - { - const auto& type = program.get_operator_info(container[index].id); - // this is a child to someone - if (children_left != 0) - children_left--; - if (type.argc.argc > 0) - children_left += type.argc.argc; - index++; - } while (children_left > 0); - - return index; - } - - void crossover_t::transfer_backward(stack_allocator& from, stack_allocator& to, crossover_t::op_iter begin, crossover_t::op_iter end) - { - for (auto it = begin; it != end; it--) - { - if (it->is_value) - from.transfer_bytes(to, it->type_size); - } - } - - void crossover_t::transfer_forward(stack_allocator& from, stack_allocator& to, crossover_t::op_iter begin, crossover_t::op_iter end) - { - // now copy back into the respective children - for (auto it = begin; it != end; it++) - { - if (it->is_value) - from.transfer_bytes(to, it->type_size); - } - } - tree_t mutation_t::apply(gp_program& program, const tree_t& p) { auto c = p; @@ -193,38 +157,15 @@ namespace blt::gp auto& ops = c.get_operations(); auto& vals = c.get_values(); - auto point = program.get_random().get_size_t(0ul, ops.size()); + auto point = static_cast(program.get_random().get_size_t(0ul, ops.size())); const auto& type_info = program.get_operator_info(ops[point].id); - blt::i64 children_left = 0; - blt::size_t index = point; - - do - { - const auto& type = program.get_operator_info(ops[index].id); - - // this is a child to someone - if (children_left != 0) - children_left--; - if (type.argc.argc > 0) - children_left += type.argc.argc; - index++; - } while (children_left > 0); - - auto begin_p = ops.begin() + static_cast(point); - auto end_p = ops.begin() + static_cast(index); + auto begin_p = ops.begin() + point; + auto end_p = ops.begin() + find_endpoint(program, ops, point); stack_allocator after_stack; - //std::vector after_ops; - for (auto it = ops.end() - 1; it != end_p - 1; it--) - { - if (it->is_value) - { - vals.transfer_bytes(after_stack, it->type_size); - //after_ops.push_back(*it); - } - } + transfer_backward(vals, after_stack, ops.end() - 1, end_p - 1); for (auto it = end_p - 1; it != begin_p - 1; it--) { @@ -263,4 +204,41 @@ namespace blt::gp mutation_t::config_t::config_t(): generator(grow_generator) {} + + blt::ptrdiff_t find_endpoint(blt::gp::gp_program& program, const std::vector& container, blt::ptrdiff_t index) + { + blt::i64 children_left = 0; + + do + { + const auto& type = program.get_operator_info(container[index].id); + // this is a child to someone + if (children_left != 0) + children_left--; + if (type.argc.argc > 0) + children_left += type.argc.argc; + index++; + } while (children_left > 0); + + return index; + } + + void transfer_backward(stack_allocator& from, stack_allocator& to, detail::op_iter begin, detail::op_iter end) + { + for (auto it = begin; it != end; it--) + { + if (it->is_value) + from.transfer_bytes(to, it->type_size); + } + } + + void transfer_forward(stack_allocator& from, stack_allocator& to, detail::op_iter begin, detail::op_iter end) + { + // now copy back into the respective children + for (auto it = begin; it != end; it++) + { + if (it->is_value) + from.transfer_bytes(to, it->type_size); + } + } } \ No newline at end of file