From f6d8073be9e633bcdc6bdc7a9f3825453f553368 Mon Sep 17 00:00:00 2001 From: Brett Date: Tue, 29 Apr 2025 13:42:35 -0400 Subject: [PATCH] some resolver --- CMakeLists.txt | 2 +- include/blt/gp/transformers.h | 4 +++ include/blt/gp/tree.h | 18 ++++++----- src/transformers.cpp | 56 ++++++++++++++++++++++++++++++++--- src/tree.cpp | 16 ++++++---- 5 files changed, 79 insertions(+), 17 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 19c6971..2ffb533 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,7 +27,7 @@ macro(compile_options target_name) sanitizers(${target_name}) endmacro() -project(blt-gp VERSION 0.5.21) +project(blt-gp VERSION 0.5.22) include(CTest) diff --git a/include/blt/gp/transformers.h b/include/blt/gp/transformers.h index 59537c1..2eeae6e 100644 --- a/include/blt/gp/transformers.h +++ b/include/blt/gp/transformers.h @@ -95,6 +95,10 @@ namespace blt::gp { } + /** + * Apply crossover to a set of parents. Note: c1 and c2 are already filled with thier respective parent's elements. + * @return true if the crossover succeeded, otherwise return false will erase progress. + */ virtual bool apply(gp_program& program, const tree_t& p1, const tree_t& p2, tree_t& c1, tree_t& c2) = 0; [[nodiscard]] const config_t& get_config() const diff --git a/include/blt/gp/tree.h b/include/blt/gp/tree.h index 4bdab6e..ac4ed08 100644 --- a/include/blt/gp/tree.h +++ b/include/blt/gp/tree.h @@ -188,13 +188,6 @@ namespace blt::gp class tree_t { public: - struct child_t - { - ptrdiff_t start; - // one past the end - ptrdiff_t end; - }; - struct subtree_point_t { ptrdiff_t pos; @@ -211,6 +204,15 @@ namespace blt::gp } }; + struct child_t + { + ptrdiff_t start; + // one past the end + ptrdiff_t end; + + + }; + struct byte_only_transaction_t { byte_only_transaction_t(tree_t& tree, const size_t bytes): tree(tree), data(nullptr), bytes(bytes) @@ -416,6 +418,8 @@ namespace blt::gp copy_subtree(point, find_endpoint(point.pos), out_tree); } + void swap_subtrees(child_t our_subtree, tree_t& other_tree, child_t other_subtree); + /** * Swaps the subtrees between this tree and the other tree * @param our_subtree diff --git a/src/transformers.cpp b/src/transformers.cpp index 5a145e6..92ad01e 100644 --- a/src/transformers.cpp +++ b/src/transformers.cpp @@ -126,7 +126,7 @@ namespace blt::gp if (p1.size() < config.min_tree_size || p2.size() < config.min_tree_size) return false; - tree_t::subtree_point_t point1, point2; + tree_t::subtree_point_t point1, point2; // NOLINT if (config.traverse) { point1 = p1.select_subtree_traverse(config.terminal_chance, config.depth_multiplier); @@ -196,6 +196,16 @@ namespace blt::gp return idx; } + [[nodiscard]] bool handled_p1(const size_t index) const + { + return correct_types.contains(index) || p1_correct_types.contains(index); + } + + [[nodiscard]] bool handled_p2(const size_t index) const + { + return correct_types.contains(index) || p2_correct_types.contains(index); + } + void clear() { children_data_p1.clear(); @@ -214,9 +224,6 @@ namespace blt::gp } resolver; resolver.clear(); - p1.find_child_extends(resolver.children_data_p1, point1.pos, p1_info.argument_types.size()); - p2.find_child_extends(resolver.children_data_p2, point2.pos, p2_info.argument_types.size()); - // resolve type information for (size_t i = 0; i < std::min(p1_info.argument_types.size(), p2_info.argument_types.size()); i++) { @@ -251,6 +258,47 @@ namespace blt::gp resolver.p1_correct_types.insert(i); } } + // next we need to figure out which types need to be swapped + for (size_t i = 0; i < p1_info.argument_types.size(); i++) + { + if (resolver.handled_p2(i)) + continue; + if (auto index = resolver.get_p1_index(p1_info.argument_types[i].id)) + resolver.swap_types.push_back({*index, i}); + else + { + BLT_WARN("Unable to process type {} in p1", p1_info.argument_types[i].id); + return false; + } + } + for (size_t i = 0; i < p2_info.argument_types.size(); i++) + { + if (resolver.handled_p1(i)) + continue; + if (auto index = resolver.get_p2_index(p2_info.argument_types[i].id)) + resolver.swap_types.push_back({i, *index}); + else + { + BLT_WARN("Unable to process type {} in p2", p2_info.argument_types[i].id); + return false; + } + } + + // now we do the swap + + p1.find_child_extends(resolver.children_data_p1, point1.pos, p1_info.argument_types.size()); + p2.find_child_extends(resolver.children_data_p2, point2.pos, p2_info.argument_types.size()); + + for (const auto& [index1, index2] : resolver.p1_reorder_types) + c1.swap_subtrees(resolver.children_data_p1[index1], c1, resolver.children_data_p1[index2]); + + for (const auto& [index1, index2] : resolver.p2_reorder_types) + c2.swap_subtrees(resolver.children_data_p2[index1], c2, resolver.children_data_p2[index2]); + + for (const auto& [p1_index, p2_index] : resolver.swap_types) + { + + } #if BLT_DEBUG_LEVEL >= 2 if (!c1.check(detail::debug::context_ptr) || !c2.check(detail::debug::context_ptr)) diff --git a/src/tree.cpp b/src/tree.cpp index d903c19..fd45888 100644 --- a/src/tree.cpp +++ b/src/tree.cpp @@ -293,13 +293,13 @@ namespace blt::gp stack.copy_from(values, for_bytes, after_bytes); } - void tree_t::swap_subtrees(const subtree_point_t our_subtree, tree_t& other_tree, const subtree_point_t other_subtree) + void tree_t::swap_subtrees(const child_t our_subtree, tree_t& other_tree, const child_t other_subtree) { - const auto c1_subtree_begin_itr = operations.begin() + our_subtree.pos; - const auto c1_subtree_end_itr = operations.begin() + find_endpoint(our_subtree.pos); + const auto c1_subtree_begin_itr = operations.begin() + our_subtree.start; + const auto c1_subtree_end_itr = operations.begin() + our_subtree.end; - const auto c2_subtree_begin_itr = other_tree.operations.begin() + other_subtree.pos; - const auto c2_subtree_end_itr = other_tree.operations.begin() + other_tree.find_endpoint(other_subtree.pos); + const auto c2_subtree_begin_itr = other_tree.operations.begin() + other_subtree.start; + const auto c2_subtree_end_itr = other_tree.operations.begin() + other_subtree.end; thread_local tracked_vector c1_subtree_operators; thread_local tracked_vector c2_subtree_operators; @@ -376,6 +376,12 @@ namespace blt::gp other_tree.operations.insert(insert_point_c2, c1_subtree_operators.begin(), c1_subtree_operators.end()); } + void tree_t::swap_subtrees(const subtree_point_t our_subtree, tree_t& other_tree, const subtree_point_t other_subtree) + { + swap_subtrees(child_t{our_subtree.pos, find_endpoint(our_subtree.pos)}, other_tree, + child_t{other_subtree.pos, find_endpoint(other_subtree.pos)}); + } + void tree_t::replace_subtree(const subtree_point_t point, const ptrdiff_t extent, tree_t& other_tree) { const auto point_begin_itr = operations.begin() + point.pos;