some resolver
parent
21ceb2322b
commit
f6d8073be9
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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))
|
||||||
|
|
16
src/tree.cpp
16
src/tree.cpp
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue