cleanup to crossover

thread
Brett 2024-07-20 15:45:07 -04:00
parent fc7cd292af
commit f62494d7d8
4 changed files with 56 additions and 75 deletions

View File

@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.25) cmake_minimum_required(VERSION 3.25)
project(blt-gp VERSION 0.0.91) project(blt-gp VERSION 0.0.92)
include(CTest) include(CTest)

View File

@ -27,11 +27,20 @@
namespace blt::gp namespace blt::gp
{ {
namespace detail
{
using op_iter = std::vector<blt::gp::op_container_t>::iterator;
}
blt::ptrdiff_t find_endpoint(blt::gp::gp_program& program, const std::vector<blt::gp::op_container_t>& 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 class crossover_t
{ {
public: public:
using op_iter = std::vector<blt::gp::op_container_t>::iterator;
enum class error_t enum class error_t
{ {
NO_VALID_TYPE, NO_VALID_TYPE,
@ -64,12 +73,6 @@ namespace blt::gp
blt::expected<crossover_t::crossover_point_t, error_t> get_crossover_point(gp_program& program, const tree_t& c1, const tree_t& c2) const; blt::expected<crossover_t::crossover_point_t, error_t> 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<blt::gp::op_container_t>& 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. * 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 * the parents are not modified during this process

@ -1 +1 @@
Subproject commit 60f77961fbbd4a1a06adbef984d838c5b49b3718 Subproject commit cd5c98d748be0ceb7011fd0aaf0eec8140d97cc6

View File

@ -51,12 +51,13 @@ namespace blt::gp
stack_allocator& c1_stack_init = c1.get_values(); stack_allocator& c1_stack_init = c1.get_values();
stack_allocator& c2_stack_init = c2.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<op_container_t> c1_operators; std::vector<op_container_t> c1_operators;
std::vector<op_container_t> c2_operators; std::vector<op_container_t> 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); 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); c2_operators.push_back(op);
stack_allocator c1_stack_after_copy; stack_allocator c1_stack_after_copy;
@ -149,43 +150,6 @@ namespace blt::gp
return crossover_point_t{static_cast<blt::ptrdiff_t>(crossover_point), static_cast<blt::ptrdiff_t>(attempted_point)}; return crossover_point_t{static_cast<blt::ptrdiff_t>(crossover_point), static_cast<blt::ptrdiff_t>(attempted_point)};
} }
blt::ptrdiff_t crossover_t::find_endpoint(blt::gp::gp_program& program, const std::vector<blt::gp::op_container_t>& 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) tree_t mutation_t::apply(gp_program& program, const tree_t& p)
{ {
auto c = p; auto c = p;
@ -193,38 +157,15 @@ namespace blt::gp
auto& ops = c.get_operations(); auto& ops = c.get_operations();
auto& vals = c.get_values(); auto& vals = c.get_values();
auto point = program.get_random().get_size_t(0ul, ops.size()); auto point = static_cast<blt::ptrdiff_t>(program.get_random().get_size_t(0ul, ops.size()));
const auto& type_info = program.get_operator_info(ops[point].id); const auto& type_info = program.get_operator_info(ops[point].id);
blt::i64 children_left = 0; auto begin_p = ops.begin() + point;
blt::size_t index = point; auto end_p = ops.begin() + find_endpoint(program, ops, 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<blt::ptrdiff_t>(point);
auto end_p = ops.begin() + static_cast<blt::ptrdiff_t>(index);
stack_allocator after_stack; stack_allocator after_stack;
//std::vector<op_container_t> after_ops;
for (auto it = ops.end() - 1; it != end_p - 1; it--) transfer_backward(vals, after_stack, ops.end() - 1, end_p - 1);
{
if (it->is_value)
{
vals.transfer_bytes(after_stack, it->type_size);
//after_ops.push_back(*it);
}
}
for (auto it = end_p - 1; it != begin_p - 1; it--) 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) mutation_t::config_t::config_t(): generator(grow_generator)
{} {}
blt::ptrdiff_t find_endpoint(blt::gp::gp_program& program, const std::vector<blt::gp::op_container_t>& 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);
}
}
} }