some resolver

main
Brett 2025-04-29 13:42:35 -04:00
parent 21ceb2322b
commit f6d8073be9
5 changed files with 79 additions and 17 deletions

View File

@ -27,7 +27,7 @@ macro(compile_options target_name)
sanitizers(${target_name}) sanitizers(${target_name})
endmacro() endmacro()
project(blt-gp VERSION 0.5.21) project(blt-gp VERSION 0.5.22)
include(CTest) include(CTest)

View File

@ -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; 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 [[nodiscard]] const config_t& get_config() const

View File

@ -188,13 +188,6 @@ namespace blt::gp
class tree_t class tree_t
{ {
public: public:
struct child_t
{
ptrdiff_t start;
// one past the end
ptrdiff_t end;
};
struct subtree_point_t struct subtree_point_t
{ {
ptrdiff_t pos; 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 struct byte_only_transaction_t
{ {
byte_only_transaction_t(tree_t& tree, const size_t bytes): tree(tree), data(nullptr), bytes(bytes) 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); 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 * Swaps the subtrees between this tree and the other tree
* @param our_subtree * @param our_subtree

View File

@ -126,7 +126,7 @@ namespace blt::gp
if (p1.size() < config.min_tree_size || p2.size() < config.min_tree_size) if (p1.size() < config.min_tree_size || p2.size() < config.min_tree_size)
return false; return false;
tree_t::subtree_point_t point1, point2; tree_t::subtree_point_t point1, point2; // NOLINT
if (config.traverse) if (config.traverse)
{ {
point1 = p1.select_subtree_traverse(config.terminal_chance, config.depth_multiplier); point1 = p1.select_subtree_traverse(config.terminal_chance, config.depth_multiplier);
@ -196,6 +196,16 @@ namespace blt::gp
return idx; 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() void clear()
{ {
children_data_p1.clear(); children_data_p1.clear();
@ -214,9 +224,6 @@ namespace blt::gp
} resolver; } resolver;
resolver.clear(); 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 // resolve type information
for (size_t i = 0; i < std::min(p1_info.argument_types.size(), p2_info.argument_types.size()); i++) 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); 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 BLT_DEBUG_LEVEL >= 2
if (!c1.check(detail::debug::context_ptr) || !c2.check(detail::debug::context_ptr)) if (!c1.check(detail::debug::context_ptr) || !c2.check(detail::debug::context_ptr))

View File

@ -293,13 +293,13 @@ namespace blt::gp
stack.copy_from(values, for_bytes, after_bytes); 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_begin_itr = operations.begin() + our_subtree.start;
const auto c1_subtree_end_itr = operations.begin() + find_endpoint(our_subtree.pos); 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_begin_itr = other_tree.operations.begin() + other_subtree.start;
const auto c2_subtree_end_itr = other_tree.operations.begin() + other_tree.find_endpoint(other_subtree.pos); const auto c2_subtree_end_itr = other_tree.operations.begin() + other_subtree.end;
thread_local tracked_vector<op_container_t> c1_subtree_operators; thread_local tracked_vector<op_container_t> c1_subtree_operators;
thread_local tracked_vector<op_container_t> c2_subtree_operators; thread_local tracked_vector<op_container_t> 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()); 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) 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; const auto point_begin_itr = operations.begin() + point.pos;