silly crossover

thread
Brett 2024-07-03 14:04:48 -04:00
parent 1c2d850329
commit 9faf7e5c61
4 changed files with 135 additions and 12 deletions

View File

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

View File

@ -36,6 +36,7 @@
#include <blt/gp/generators.h>
#include <blt/gp/tree.h>
#include <blt/std/logging.h>
#include <blt/gp/transformers.h>
static constexpr long SEED = 41912;
@ -94,13 +95,39 @@ int main()
blt::gp::ramped_half_initializer_t pop_init;
auto pop = pop_init.generate(blt::gp::initializer_arguments{program, type_system.get_type<float>().id(), 500, 3, 10});
// for (auto& tree : pop.getIndividuals())
// {
// auto value = tree.get_evaluation_value<float>(nullptr);
//
// BLT_TRACE(value);
// }
for (auto& tree : pop.getIndividuals())
blt::gp::crossover_t crossover;
auto& ind = pop.getIndividuals();
auto results = crossover.apply(program, ind[0], ind[1]);
if (results.has_value())
{
auto value = tree.get_evaluation_value<float>(nullptr);
BLT_TRACE(value);
BLT_TRACE("Parent 1: %f", ind[0].get_evaluation_value<float>(nullptr));
BLT_TRACE("Parent 2: %f", ind[1].get_evaluation_value<float>(nullptr));
BLT_TRACE("------------");
BLT_TRACE("Child 1: %f", results->child1.get_evaluation_value<float>(nullptr));
BLT_TRACE("Child 2: %f", results->child2.get_evaluation_value<float>(nullptr));
} else
{
switch (results.error())
{
case blt::gp::crossover_t::error_t::NO_VALID_TYPE:
BLT_ERROR("No valid type!");
break;
case blt::gp::crossover_t::error_t::TREE_TOO_SMALL:
BLT_ERROR("Tree is too small!");
break;
}
}
return 0;
}

View File

@ -36,8 +36,8 @@ namespace blt::gp
func(func), transfer(transfer), id(id), is_value(is_value)
{}
detail::callable_t& func;
detail::transfer_t& transfer;
std::reference_wrapper<detail::callable_t> func;
std::reference_wrapper<detail::transfer_t> transfer;
operator_id id;
bool is_value;
};

View File

@ -27,6 +27,9 @@ namespace blt::gp
const auto& config = program.get_config();
result_t result{p1, p2};
BLT_INFO("Child 1 Stack empty? %s", result.child1.get_values().empty() ? "true" : "false");
BLT_INFO("Child 2 Stack empty? %s", result.child2.get_values().empty() ? "true" : "false");
auto& c1 = result.child1;
auto& c2 = result.child2;
@ -86,6 +89,7 @@ namespace blt::gp
index++;
} while (children_left > 0);
auto crossover_point_begin_itr = c1_ops.begin() + static_cast<blt::ptrdiff_t>(crossover_point);
auto crossover_point_end_itr = c1_ops.begin() + static_cast<blt::ptrdiff_t>(index);
children_left = 0;
@ -104,19 +108,111 @@ namespace blt::gp
break;
} while (true);
auto found_point_end_iter = c2_ops.begin() + static_cast<blt::ptrdiff_t>(index);
auto found_point_begin_itr = c2_ops.begin() + static_cast<blt::ptrdiff_t>(attempted_point);
auto found_point_end_itr = c2_ops.begin() + static_cast<blt::ptrdiff_t>(index);
stack_allocator c1_stack_init = c1.get_values();
stack_allocator c2_stack_init = c2.get_values();
stack_allocator& c1_stack_init = c1.get_values();
stack_allocator& c2_stack_init = c2.get_values();
std::vector<op_container_t> c1_operators;
std::vector<op_container_t> c2_operators;
for (const auto& op : blt::enumerate(c1_ops.begin() + static_cast<blt::ptrdiff_t>(crossover_point), crossover_point_end_itr))
for (const auto& op : blt::enumerate(crossover_point_begin_itr, crossover_point_end_itr))
c1_operators.push_back(op);
for (const auto& op : blt::enumerate(c2_ops.begin() + static_cast<blt::ptrdiff_t>(attempted_point), found_point_end_iter))
for (const auto& op : blt::enumerate(found_point_begin_itr, found_point_end_itr))
c2_operators.push_back(op);
stack_allocator c1_stack_after_copy;
stack_allocator c1_stack_for_copy;
stack_allocator c2_stack_after_copy;
stack_allocator c2_stack_for_copy;
// transfer all values after the crossover point. these will need to be transferred back to child2
for (auto it = c1_ops.end() - 1; it != crossover_point_end_itr - 1; it--)
{
if (it->is_value)
it->transfer(c1_stack_after_copy, c1_stack_init, -1);
}
// transfer all values for the crossover point.
for (auto it = crossover_point_end_itr - 1; it != crossover_point_begin_itr - 1; it--)
{
if (it->is_value)
it->transfer(c1_stack_for_copy, c1_stack_init, -1);
}
// transfer child2 values for copying back into c1
for (auto it = c2_ops.end() - 1; it != found_point_end_itr - 1; it--)
{
if (it->is_value)
it->transfer(c2_stack_after_copy, c2_stack_init, -1);
}
for (auto it = found_point_end_itr - 1; it != found_point_begin_itr - 1; it--)
{
if (it->is_value)
it->transfer(c2_stack_for_copy, c2_stack_init, -1);
}
BLT_TRACE("c1_stack_after_copy empty? %s", c1_stack_after_copy.empty() ? "true" : "false");
BLT_TRACE("c1_stack_for_copy empty? %s", c1_stack_for_copy.empty() ? "true" : "false");
BLT_TRACE("c2_stack_after_copy empty? %s", c2_stack_after_copy.empty() ? "true" : "false");
BLT_TRACE("c2_stack_for_copy empty? %s", c2_stack_for_copy.empty() ? "true" : "false");
BLT_INFO("Child 1 Stack empty? %s", result.child1.get_values().empty() ? "true" : "false");
BLT_INFO("Child 2 Stack empty? %s", result.child2.get_values().empty() ? "true" : "false");
// now copy back into the respective children
for (auto it = found_point_begin_itr; it != found_point_end_itr; it++)
{
if (it->is_value)
it->transfer(c1.get_values(), c2_stack_for_copy, -1);
}
for (auto it = crossover_point_begin_itr; it != crossover_point_end_itr; it++)
{
if (it->is_value)
it->transfer(c2.get_values(), c1_stack_for_copy, -1);
}
BLT_TRACE("c1_stack_after_copy empty? %s", c1_stack_after_copy.empty() ? "true" : "false");
BLT_TRACE("c1_stack_for_copy empty? %s", c1_stack_for_copy.empty() ? "true" : "false");
BLT_TRACE("c2_stack_after_copy empty? %s", c2_stack_after_copy.empty() ? "true" : "false");
BLT_TRACE("c2_stack_for_copy empty? %s", c2_stack_for_copy.empty() ? "true" : "false");
BLT_INFO("Child 1 Stack empty? %s", result.child1.get_values().empty() ? "true" : "false");
BLT_INFO("Child 2 Stack empty? %s", result.child2.get_values().empty() ? "true" : "false");
// now copy after the crossover point back to the correct children
for (auto it = crossover_point_end_itr; it != c1_ops.end(); it++)
{
if (it->is_value)
it->transfer(c1.get_values(), c1_stack_after_copy, -1);
}
for (auto it = found_point_end_itr; it != c2_ops.end(); it++)
{
if (it->is_value)
it->transfer(c2.get_values(), c2_stack_after_copy, -1);
}
BLT_TRACE("c1_stack_after_copy empty? %s", c1_stack_after_copy.empty() ? "true" : "false");
BLT_TRACE("c1_stack_for_copy empty? %s", c1_stack_for_copy.empty() ? "true" : "false");
BLT_TRACE("c2_stack_after_copy empty? %s", c2_stack_after_copy.empty() ? "true" : "false");
BLT_TRACE("c2_stack_for_copy empty? %s", c2_stack_for_copy.empty() ? "true" : "false");
// now swap the operators
auto insert_point_c1 = crossover_point_begin_itr - 1;
auto insert_point_c2 = found_point_begin_itr - 1;
// invalidates [begin, end()) so the insert points should be fine
c1_ops.erase(crossover_point_begin_itr, crossover_point_end_itr);
c2_ops.erase(found_point_begin_itr, found_point_end_itr);
c1_ops.insert(++insert_point_c1, c2_operators.begin(), c2_operators.end());
c1_ops.insert(++insert_point_c2, c1_operators.begin(), c1_operators.end());
BLT_INFO("Child 1 Stack empty? %s", result.child1.get_values().empty() ? "true" : "false");
BLT_INFO("Child 2 Stack empty? %s", result.child2.get_values().empty() ? "true" : "false");
return result;
}
}