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})
endmacro()
project(blt-gp VERSION 0.5.21)
project(blt-gp VERSION 0.5.22)
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;
[[nodiscard]] const config_t& get_config() const

View File

@ -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

View File

@ -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))

View File

@ -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<op_container_t> c1_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());
}
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;