crossover no longer produces an error on test 5
parent
9faf7e5c61
commit
30a4a0e8d7
|
@ -1,5 +1,5 @@
|
|||
cmake_minimum_required(VERSION 3.25)
|
||||
project(blt-gp VERSION 0.0.48)
|
||||
project(blt-gp VERSION 0.0.49)
|
||||
|
||||
include(CTest)
|
||||
|
||||
|
@ -7,6 +7,7 @@ option(ENABLE_ADDRSAN "Enable the address sanitizer" OFF)
|
|||
option(ENABLE_UBSAN "Enable the ub sanitizer" OFF)
|
||||
option(ENABLE_TSAN "Enable the thread data race sanitizer" OFF)
|
||||
option(BUILD_EXAMPLES "Build example programs. This is a single executable" OFF)
|
||||
option(DEBUG_LEVEL "Enable debug features which prints extra information to the console, might slow processing down. [0, 3)" 0)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
|
||||
|
@ -21,6 +22,7 @@ target_compile_options(blt-gp PRIVATE -Wall -Wextra -Werror -Wpedantic -Wno-comm
|
|||
target_link_options(blt-gp PRIVATE -Wall -Wextra -Werror -Wpedantic -Wno-comment)
|
||||
|
||||
target_link_libraries(blt-gp PRIVATE BLT)
|
||||
target_compile_definitions(blt-gp PRIVATE BLT_DEBUG_LEVEL=${DEBUG_LEVEL})
|
||||
|
||||
if (${ENABLE_ADDRSAN} MATCHES ON)
|
||||
target_compile_options(blt-gp PRIVATE -fsanitize=address)
|
||||
|
@ -48,6 +50,7 @@ if (${BUILD_EXAMPLES})
|
|||
|
||||
target_compile_options(${name}-example PRIVATE -Wall -Wextra -Wpedantic -Wno-comment)
|
||||
target_link_options(${name}-example PRIVATE -Wall -Wextra -Wpedantic -Wno-comment)
|
||||
target_compile_definitions(${name}-example PRIVATE BLT_DEBUG_LEVEL=${DEBUG_LEVEL})
|
||||
|
||||
if (${ENABLE_ADDRSAN} MATCHES ON)
|
||||
target_compile_options(${name}-example PRIVATE -fsanitize=address)
|
||||
|
|
|
@ -43,22 +43,22 @@ static constexpr long SEED = 41912;
|
|||
blt::gp::type_provider type_system;
|
||||
blt::gp::gp_program program(type_system, std::mt19937_64{SEED}); // NOLINT
|
||||
|
||||
blt::gp::operation_t add([](float a, float b) { return a + b; });
|
||||
blt::gp::operation_t sub([](float a, float b) { return a - b; });
|
||||
blt::gp::operation_t mul([](float a, float b) { return a * b; });
|
||||
blt::gp::operation_t pro_div([](float a, float b) { return b == 0 ? 0.0f : a / b; });
|
||||
blt::gp::operation_t add([](float a, float b) { return a + b; }); // 0
|
||||
blt::gp::operation_t sub([](float a, float b) { return a - b; }); // 1
|
||||
blt::gp::operation_t mul([](float a, float b) { return a * b; }); // 2
|
||||
blt::gp::operation_t pro_div([](float a, float b) { return b == 0 ? 0.0f : a / b; }); // 3
|
||||
|
||||
blt::gp::operation_t op_if([](bool b, float a, float c) { return b ? a : c; });
|
||||
blt::gp::operation_t eq_f([](float a, float b) { return a == b; });
|
||||
blt::gp::operation_t eq_b([](bool a, bool b) { return a == b; });
|
||||
blt::gp::operation_t lt([](float a, float b) { return a < b; });
|
||||
blt::gp::operation_t gt([](float a, float b) { return a > b; });
|
||||
blt::gp::operation_t op_and([](bool a, bool b) { return a && b; });
|
||||
blt::gp::operation_t op_or([](bool a, bool b) { return a || b; });
|
||||
blt::gp::operation_t op_xor([](bool a, bool b) { return static_cast<bool>(a ^ b); });
|
||||
blt::gp::operation_t op_not([](bool b) { return !b; });
|
||||
blt::gp::operation_t op_if([](bool b, float a, float c) { return b ? a : c; }); // 4
|
||||
blt::gp::operation_t eq_f([](float a, float b) { return a == b; }); // 5
|
||||
blt::gp::operation_t eq_b([](bool a, bool b) { return a == b; }); // 6
|
||||
blt::gp::operation_t lt([](float a, float b) { return a < b; }); // 7
|
||||
blt::gp::operation_t gt([](float a, float b) { return a > b; }); // 8
|
||||
blt::gp::operation_t op_and([](bool a, bool b) { return a && b; }); // 9
|
||||
blt::gp::operation_t op_or([](bool a, bool b) { return a || b; }); // 10
|
||||
blt::gp::operation_t op_xor([](bool a, bool b) { return static_cast<bool>(a ^ b); }); // 11
|
||||
blt::gp::operation_t op_not([](bool b) { return !b; }); // 12
|
||||
|
||||
blt::gp::operation_t lit([]() {
|
||||
blt::gp::operation_t lit([]() { // 13
|
||||
//static std::uniform_real_distribution<float> dist(-32000, 32000);
|
||||
static std::uniform_real_distribution<float> dist(0.0f, 10.0f);
|
||||
return dist(program.get_random());
|
||||
|
@ -107,6 +107,7 @@ int main()
|
|||
|
||||
auto& ind = pop.getIndividuals();
|
||||
auto results = crossover.apply(program, ind[0], ind[1]);
|
||||
BLT_INFO("Post crossover:");
|
||||
|
||||
if (results.has_value())
|
||||
{
|
||||
|
|
|
@ -54,7 +54,7 @@ namespace blt::gp
|
|||
// context*, read stack, write stack
|
||||
using callable_t = std::function<void(void*, stack_allocator&, stack_allocator&)>;
|
||||
// to, from
|
||||
using transfer_t = std::function<void(stack_allocator&, stack_allocator&, blt::ptrdiff_t)>;
|
||||
using transfer_t = std::function<void(stack_allocator&, stack_allocator&)>;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -117,11 +117,15 @@ namespace blt::gp
|
|||
BLT_ASSERT(info.argc.argc_context - info.argc.argc <= 1 && "Cannot pass multiple context as arguments!");
|
||||
|
||||
info.function = op.template make_callable<Context>();
|
||||
info.transfer = [](stack_allocator& to, stack_allocator& from, blt::ptrdiff_t offset) {
|
||||
if (offset < 0)
|
||||
to.push(from.pop<Return>());
|
||||
else
|
||||
to.push(from.from<Return>(offset));
|
||||
info.transfer = [](stack_allocator& to, stack_allocator& from) {
|
||||
#if BLT_DEBUG_LEVEL >= 3
|
||||
auto value = from.pop<Return>();
|
||||
BLT_TRACE_STREAM << value << "\n";
|
||||
to.push(value);
|
||||
#else
|
||||
to.push(from.pop<Return>());
|
||||
#endif
|
||||
|
||||
};
|
||||
storage.operators.push_back(info);
|
||||
if (is_static)
|
||||
|
|
|
@ -106,8 +106,25 @@ namespace blt::gp
|
|||
|
||||
void pop_bytes(blt::ptrdiff_t bytes)
|
||||
{
|
||||
#if BLT_DEBUG_LEVEL >= 3
|
||||
blt::size_t counter = 0;
|
||||
#endif
|
||||
while (bytes > 0)
|
||||
{
|
||||
#if BLT_DEBUG_LEVEL > 0
|
||||
if (head == nullptr)
|
||||
{
|
||||
BLT_WARN("Head is nullptr, unable to pop bytes!");
|
||||
BLT_WARN("This error is normally caused by an invalid tree!");
|
||||
#if BLT_DEBUG_LEVEL >= 3
|
||||
BLT_WARN("Made it to %ld iterations", counter);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
#if BLT_DEBUG_LEVEL >= 3
|
||||
counter++;
|
||||
#endif
|
||||
#endif
|
||||
auto diff = head->used_bytes_in_block() - bytes;
|
||||
// if there is not enough room left to pop completely off the block, then move to the next previous block
|
||||
// and pop from it, update the amount of bytes to reflect the amount removed from the current block
|
||||
|
|
|
@ -26,9 +26,11 @@ namespace blt::gp
|
|||
{
|
||||
const auto& config = program.get_config();
|
||||
result_t result{p1, p2};
|
||||
|
||||
|
||||
#if BLT_DEBUG_LEVEL > 0
|
||||
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");
|
||||
#endif
|
||||
|
||||
auto& c1 = result.child1;
|
||||
auto& c2 = result.child2;
|
||||
|
@ -82,6 +84,9 @@ namespace blt::gp
|
|||
do
|
||||
{
|
||||
const auto& type = program.get_operator_info(c1_ops[index].id);
|
||||
#if BLT_DEBUG_LEVEL > 1
|
||||
BLT_TRACE("Crossover type: %s, op %ld", std::string(program.get_typesystem().get_type(type.return_type).name()).c_str(), c1_ops[index].id);
|
||||
#endif
|
||||
if (type.argc.argc > 0)
|
||||
children_left += type.argc.argc;
|
||||
else
|
||||
|
@ -91,6 +96,9 @@ namespace blt::gp
|
|||
|
||||
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);
|
||||
#if BLT_DEBUG_LEVEL > 0
|
||||
BLT_TRACE("[%ld %ld) %ld", crossover_point, index, index - crossover_point);
|
||||
#endif
|
||||
|
||||
children_left = 0;
|
||||
index = attempted_point;
|
||||
|
@ -98,18 +106,22 @@ namespace blt::gp
|
|||
do
|
||||
{
|
||||
const auto& type = program.get_operator_info(c2_ops[index].id);
|
||||
#if BLT_DEBUG_LEVEL > 1
|
||||
BLT_TRACE("Found type: %s, op: %ld", std::string(program.get_typesystem().get_type(type.return_type).name()).c_str(), c2_ops[index].id);
|
||||
#endif
|
||||
if (type.argc.argc > 0)
|
||||
children_left += type.argc.argc;
|
||||
else
|
||||
children_left--;
|
||||
if (children_left > 0)
|
||||
index++;
|
||||
else
|
||||
break;
|
||||
} while (true);
|
||||
index++;
|
||||
} while (children_left > 0);
|
||||
|
||||
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);
|
||||
|
||||
#if BLT_DEBUG_LEVEL > 0
|
||||
BLT_TRACE("[%ld %ld) %ld", attempted_point, index, index - attempted_point);
|
||||
#endif
|
||||
|
||||
stack_allocator& c1_stack_init = c1.get_values();
|
||||
stack_allocator& c2_stack_init = c2.get_values();
|
||||
|
@ -121,84 +133,93 @@ namespace blt::gp
|
|||
c1_operators.push_back(op);
|
||||
for (const auto& op : blt::enumerate(found_point_begin_itr, found_point_end_itr))
|
||||
c2_operators.push_back(op);
|
||||
|
||||
#if BLT_DEBUG_LEVEL > 0
|
||||
BLT_TRACE("Sizes: %ld %ld || Ops size: %ld %ld", c1_operators.size(), c2_operators.size(), c1_ops.size(), c2_ops.size());
|
||||
#endif
|
||||
|
||||
stack_allocator c1_stack_after_copy;
|
||||
stack_allocator c1_stack_for_copy;
|
||||
stack_allocator c2_stack_after_copy;
|
||||
stack_allocator c2_stack_for_copy;
|
||||
|
||||
|
||||
#if BLT_DEBUG_LEVEL > 1
|
||||
BLT_DEBUG("Transferring past crossover 1:");
|
||||
#endif
|
||||
// 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);
|
||||
it->transfer(c1_stack_after_copy, c1_stack_init);
|
||||
}
|
||||
|
||||
|
||||
#if BLT_DEBUG_LEVEL > 1
|
||||
BLT_DEBUG("Transferring for crossover 1:");
|
||||
#endif
|
||||
// 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);
|
||||
it->transfer(c1_stack_for_copy, c1_stack_init);
|
||||
}
|
||||
|
||||
|
||||
#if BLT_DEBUG_LEVEL > 1
|
||||
BLT_DEBUG("Transferring past crossover 2:");
|
||||
#endif
|
||||
// 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);
|
||||
it->transfer(c2_stack_after_copy, c2_stack_init);
|
||||
}
|
||||
|
||||
|
||||
#if BLT_DEBUG_LEVEL > 1
|
||||
BLT_DEBUG("Transferring for crossover 2:");
|
||||
#endif
|
||||
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);
|
||||
it->transfer(c2_stack_for_copy, c2_stack_init);
|
||||
}
|
||||
|
||||
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");
|
||||
|
||||
|
||||
#if BLT_DEBUG_LEVEL > 1
|
||||
BLT_DEBUG("Transferring back for crossover 1:");
|
||||
#endif
|
||||
// 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);
|
||||
it->transfer(c1.get_values(), c2_stack_for_copy);
|
||||
}
|
||||
|
||||
|
||||
#if BLT_DEBUG_LEVEL > 1
|
||||
BLT_DEBUG("Transferring back for crossover 2:");
|
||||
#endif
|
||||
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);
|
||||
it->transfer(c2.get_values(), c1_stack_for_copy);
|
||||
}
|
||||
|
||||
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");
|
||||
|
||||
|
||||
#if BLT_DEBUG_LEVEL > 1
|
||||
BLT_DEBUG("Transferring back after crossover 1:");
|
||||
#endif
|
||||
// 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);
|
||||
it->transfer(c1.get_values(), c1_stack_after_copy);
|
||||
}
|
||||
|
||||
|
||||
#if BLT_DEBUG_LEVEL > 1
|
||||
BLT_DEBUG("Transferring back after crossover 2:");
|
||||
#endif
|
||||
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);
|
||||
it->transfer(c2.get_values(), c2_stack_after_copy);
|
||||
}
|
||||
|
||||
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;
|
||||
|
@ -208,10 +229,7 @@ namespace blt::gp
|
|||
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");
|
||||
c2_ops.insert(++insert_point_c2, c1_operators.begin(), c1_operators.end());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ namespace blt::gp
|
|||
operations_stack.pop_back();
|
||||
if (operation.is_value)
|
||||
{
|
||||
operation.transfer(values_process, value_stack, -1);
|
||||
operation.transfer(values_process, value_stack);
|
||||
continue;
|
||||
}
|
||||
operation.func(context, values_process, value_stack);
|
||||
|
|
Loading…
Reference in New Issue