diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 0000000..f63addd --- /dev/null +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/.idea/editor.xml b/.idea/editor.xml new file mode 100644 index 0000000..46540da --- /dev/null +++ b/.idea/editor.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index 79b3c94..0b76fe5 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,4 +1,7 @@ + + \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index a990085..7389c4f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.25) -project(blt-gp VERSION 0.1.56) +project(blt-gp VERSION 0.2.1) include(CTest) diff --git a/examples/rice_classification.cpp b/examples/rice_classification.cpp index 181aa02..71b7ec8 100644 --- a/examples/rice_classification.cpp +++ b/examples/rice_classification.cpp @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include #include #include "operations_common.h" @@ -99,7 +99,7 @@ blt::gp::operation_t op_extent([](const rice_record& rice_data) { constexpr auto fitness_function = [](blt::gp::tree_t& current_tree, blt::gp::fitness_t& fitness, blt::size_t) { for (auto& training_case : training_cases) { - auto v = current_tree.get_evaluation_value(&training_case); + auto v = current_tree.get_evaluation_value(training_case); switch (training_case.type) { case rice_type_t::Cammeo: @@ -209,7 +209,7 @@ test_results_t test_individual(blt::gp::individual_t& i) for (auto& testing_case : testing_cases) { - auto result = i.tree.get_evaluation_value(&testing_case); + auto result = i.tree.get_evaluation_value(testing_case); switch (testing_case.type) { case rice_type_t::Cammeo: diff --git a/include/blt/gp/tree.h b/include/blt/gp/tree.h index 7e3e0e2..e35ebd4 100644 --- a/include/blt/gp/tree.h +++ b/include/blt/gp/tree.h @@ -116,12 +116,17 @@ namespace blt::gp return values; } - template, bool> = true> + template || std::is_null_pointer_v), bool> = true> [[nodiscard]] evaluation_context& evaluate(const T& context) const { return (*func)(*this, const_cast(static_cast(&context))); } + [[nodiscard]] evaluation_context& evaluate() const + { + return (*func)(*this, nullptr); + } + blt::size_t get_depth(gp_program& program); /** @@ -151,6 +156,12 @@ namespace blt::gp return evaluate(context).values.template pop(); } + template + T get_evaluation_value() + { + return evaluate().values.pop(); + } + void print(gp_program& program, std::ostream& output, bool print_literals = true, bool pretty_indent = false, bool include_types = false) const; diff --git a/src/transformers.cpp b/src/transformers.cpp index a50778f..efdee82 100644 --- a/src/transformers.cpp +++ b/src/transformers.cpp @@ -81,9 +81,11 @@ namespace blt::gp c1_operators.clear(); c2_operators.clear(); + // TODO: more crossover! switch (selection) { case 0: + case 1: { // basic crossover auto crossover_point_begin_itr = c1_ops.begin() + point->p1_crossover_point; @@ -136,9 +138,6 @@ namespace blt::gp c2_ops.insert(++insert_point_c2, c1_operators.begin(), c1_operators.end()); } break; - case 1: { - - } break; default: #if BLT_DEBUG_LEVEL > 0 diff --git a/tests/evaluation_tests.cpp b/tests/evaluation_tests.cpp index fb6c524..e368b6a 100644 --- a/tests/evaluation_tests.cpp +++ b/tests/evaluation_tests.cpp @@ -22,7 +22,7 @@ #include #include -const blt::u64 SEED = std::random_device()(); +static const auto SEED_FUNC = [] { return std::random_device()(); }; struct large_256 { @@ -52,13 +52,12 @@ struct large_18290 large_18290 base{}; -blt::gp::type_provider type_system; -blt::gp::gp_program program{type_system, SEED}; +blt::gp::gp_program program{SEED_FUNC}; blt::gp::op_container_t make_container(blt::gp::operator_id id) { auto& info = program.get_operator_info(id); - return {type_system.get_type(info.return_type).size(), id, false}; + return {program.get_typesystem().get_type(info.return_type).size(), id, false}; } blt::gp::op_container_t make_value(const blt::gp::type& id) @@ -107,12 +106,12 @@ void basic_tree() blt::gp::tree_t tree{program}; tree.get_operations().push_back(make_container(sub.id)); - tree.get_operations().push_back(make_value(type_system.get_type())); - tree.get_operations().push_back(make_value(type_system.get_type())); + tree.get_operations().push_back(make_value(program.get_typesystem().get_type())); + tree.get_operations().push_back(make_value(program.get_typesystem().get_type())); tree.get_values().push(50.0f); tree.get_values().push(120.0f); - auto val = tree.get_evaluation_value(nullptr); + auto val = tree.get_evaluation_value(); BLT_TRACE(val); BLT_ASSERT(val == (120 - 50)); } @@ -125,16 +124,16 @@ void large_cross_type_tree() ops.push_back(make_container(cross_large_type.id)); ops.push_back(make_container(sub.id)); - ops.push_back(make_value(type_system.get_type())); - ops.push_back(make_value(type_system.get_type())); - ops.push_back(make_value(type_system.get_type())); + ops.push_back(make_value(program.get_typesystem().get_type())); + ops.push_back(make_value(program.get_typesystem().get_type())); + ops.push_back(make_value(program.get_typesystem().get_type())); ops.push_back(make_container(large_literal.id)); vals.push(50.0f); vals.push(120.0f); vals.push(5555.0f); - auto val = tree.get_evaluation_value(nullptr); + auto val = tree.get_evaluation_value(); blt::black_box(val); } @@ -143,11 +142,7 @@ int main() for (auto& v : base.data) v = static_cast(blt::random::murmur_random64c(691, std::numeric_limits::min(), std::numeric_limits::max())); - type_system.register_type(); - type_system.register_type(); - type_system.register_type(); - - blt::gp::operator_builder builder{type_system}; + blt::gp::operator_builder builder{}; program.set_operations(builder.build(f_literal, b_literal, add, basic_2t, sub, large_literal, cross_large_type)); basic_tree(); diff --git a/tests/gp_test_1.cpp b/tests/gp_test_1.cpp index 6d2c7cb..3a905da 100644 --- a/tests/gp_test_1.cpp +++ b/tests/gp_test_1.cpp @@ -438,9 +438,7 @@ int main() return ctx.x; }); - blt::gp::type_provider system; - system.register_type(); - blt::gp::operator_builder ops{system}; + blt::gp::operator_builder ops{}; //BLT_TRACE(blt::type_string()); //BLT_TRACE(typeid(decltype(silly_op_3)::first::type).name()); diff --git a/tests/gp_test_2.cpp b/tests/gp_test_2.cpp index 960d414..6e439dc 100644 --- a/tests/gp_test_2.cpp +++ b/tests/gp_test_2.cpp @@ -21,10 +21,9 @@ #include -static constexpr long SEED = 41912; +static const auto SEED_FUNC = [] { return std::random_device()(); }; -blt::gp::type_provider type_system; -blt::gp::gp_program program(type_system, SEED); // NOLINT +blt::gp::gp_program program(SEED_FUNC); // NOLINT blt::gp::operation_t add([](float a, float b) { BLT_TRACE("a: %f + b: %f = %f", a, b, a + b); @@ -53,16 +52,15 @@ auto lit = blt::gp::operation_t([]() { */ int main() { - type_system.register_type(); - - blt::gp::operator_builder silly{type_system}; + blt::gp::operator_builder silly{}; program.set_operations(silly.build(add, sub, mul, pro_div, lit)); blt::gp::grow_generator_t grow; - auto tree = grow.generate(blt::gp::generator_arguments{program, type_system.get_type().id(), 3, 7}); + blt::gp::tree_t tree{program}; + grow.generate(tree, blt::gp::generator_arguments{program, program.get_typesystem().get_type().id(), 3, 7}); - auto value = tree.get_evaluation_value(nullptr); + auto value = tree.get_evaluation_value(); BLT_TRACE(value); diff --git a/tests/gp_test_3.cpp b/tests/gp_test_3.cpp index d961b3d..820f928 100644 --- a/tests/gp_test_3.cpp +++ b/tests/gp_test_3.cpp @@ -20,10 +20,9 @@ #include #include -static constexpr long SEED = 41912; +static const auto SEED_FUNC = [] { return std::random_device()(); }; -blt::gp::type_provider type_system; -blt::gp::gp_program program(type_system, SEED); // NOLINT +blt::gp::gp_program program(SEED_FUNC); // 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; }); @@ -51,16 +50,14 @@ auto lit = blt::gp::operation_t([]() { */ int main() { - type_system.register_type(); - type_system.register_type(); - - blt::gp::operator_builder silly{type_system}; + blt::gp::operator_builder silly{}; program.set_operations(silly.build(add, sub, mul, pro_div, op_if, eq_f, eq_b, lt, gt, op_and, op_or, op_xor, op_not, lit)); blt::gp::grow_generator_t grow; - auto tree = grow.generate(blt::gp::generator_arguments{program, type_system.get_type().id(), 3, 7}); + blt::gp::tree_t tree{program}; + grow.generate(tree, blt::gp::generator_arguments{program, program.get_typesystem().get_type().id(), 3, 7}); - auto value = tree.get_evaluation_value(nullptr); + auto value = tree.get_evaluation_value(); BLT_TRACE(value); diff --git a/tests/gp_test_4.cpp b/tests/gp_test_4.cpp index 585585d..3410cdd 100644 --- a/tests/gp_test_4.cpp +++ b/tests/gp_test_4.cpp @@ -20,10 +20,9 @@ #include #include -static constexpr long SEED = 41912; +static const auto SEED_FUNC = [] { return std::random_device()(); }; -blt::gp::type_provider type_system; -blt::gp::gp_program program(type_system, SEED); // NOLINT +blt::gp::gp_program program(SEED_FUNC); // 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; }); @@ -51,19 +50,16 @@ auto lit = blt::gp::operation_t([]() { */ int main() { - type_system.register_type(); - type_system.register_type(); - - blt::gp::operator_builder builder{type_system}; + blt::gp::operator_builder builder{}; program.set_operations(builder.build(add, sub, mul, pro_div, op_if, eq_f, eq_b, lt, gt, op_and, op_or, op_xor, op_not, lit)); blt::gp::ramped_half_initializer_t pop_init; - auto pop = pop_init.generate(blt::gp::initializer_arguments{program, type_system.get_type().id(), 500, 3, 10}); + auto pop = pop_init.generate(blt::gp::initializer_arguments{program, program.get_typesystem().get_type().id(), 500, 3, 10}); for (auto& tree : pop.for_each_tree()) { - auto value = tree.get_evaluation_value(nullptr); + auto value = tree.get_evaluation_value(); BLT_TRACE(value); } diff --git a/tests/gp_test_5.cpp b/tests/gp_test_5.cpp index 7ef9e7a..ad077c8 100644 --- a/tests/gp_test_5.cpp +++ b/tests/gp_test_5.cpp @@ -40,11 +40,9 @@ #include #include -static constexpr long SEED = 41912; +static const auto SEED_FUNC = [] { return std::random_device()(); }; - -blt::gp::type_provider type_system; -blt::gp::gp_program program(type_system, SEED); // NOLINT +blt::gp::gp_program program(SEED_FUNC); // NOLINT blt::gp::operation_t add([](float a, float b) { return a + b; }, "add"); // 0 blt::gp::operation_t sub([](float a, float b) { return a - b; }, "sub"); // 1 @@ -72,15 +70,12 @@ auto lit = blt::gp::operation_t([]() { */ int main() { - type_system.register_type(); - type_system.register_type(); - - blt::gp::operator_builder builder{type_system}; + blt::gp::operator_builder builder{}; program.set_operations(builder.build(add, sub, mul, pro_div, op_if, eq_f, eq_b, lt, gt, op_and, op_or, op_xor, op_not, lit)); blt::gp::ramped_half_initializer_t pop_init; - auto pop = pop_init.generate(blt::gp::initializer_arguments{program, type_system.get_type().id(), 500, 3, 10}); + auto pop = pop_init.generate(blt::gp::initializer_arguments{program, program.get_typesystem().get_type().id(), 500, 3, 10}); // for (auto& tree : pop.getIndividuals()) // { @@ -99,7 +94,7 @@ int main() BLT_INFO("Pre-Crossover:"); for (auto& tree : pop.get_individuals()) { - auto f = tree.tree.get_evaluation_value(nullptr); + auto f = tree.tree.get_evaluation_value(); pre.push_back(f); BLT_TRACE(f); } @@ -116,34 +111,31 @@ int main() second = random.get_size_t(0ul, pop.get_individuals().size()); } while (second == first); - auto results = crossover.apply(program, ind[first].tree, ind[second].tree); - if (results.has_value()) + blt::gp::tree_t child1{program}; + blt::gp::tree_t child2{program}; + // crossover function assumes that children have been copied from parents + child1.copy_fast(ind[first].tree); + child2.copy_fast(ind[second].tree); + auto results = crossover.apply(program, ind[first].tree, ind[second].tree, child1, child2); + if (results) { // bool print_literals = true; // bool pretty_print = false; // bool print_returns = false; -// BLT_TRACE("Parent 1: %f", ind[0].get_evaluation_value(nullptr)); +// BLT_TRACE("Parent 1: %f", ind[0].get_evaluation_value()); // ind[0].print(program, std::cout, print_literals, pretty_print, print_returns); -// BLT_TRACE("Parent 2: %f", ind[1].get_evaluation_value(nullptr)); +// BLT_TRACE("Parent 2: %f", ind[1].get_evaluation_value()); // ind[1].print(program, std::cout, print_literals, pretty_print, print_returns); // BLT_TRACE("------------"); -// BLT_TRACE("Child 1: %f", results->child1.get_evaluation_value(nullptr)); +// BLT_TRACE("Child 1: %f", results->child1.get_evaluation_value()); // results->child1.print(program, std::cout, print_literals, pretty_print, print_returns); -// BLT_TRACE("Child 2: %f", results->child2.get_evaluation_value(nullptr)); +// BLT_TRACE("Child 2: %f", results->child2.get_evaluation_value()); // results->child2.print(program, std::cout, print_literals, pretty_print, print_returns); - new_pop.get_individuals().emplace_back(std::move(results->child1)); - new_pop.get_individuals().emplace_back(std::move(results->child2)); + new_pop.get_individuals().emplace_back(std::move(child1)); + new_pop.get_individuals().emplace_back(std::move(child2)); } else { - switch (results.error()) - { - case blt::gp::crossover_t::error_t::NO_VALID_TYPE: - BLT_DEBUG("No valid type!"); - break; - case blt::gp::crossover_t::error_t::TREE_TOO_SMALL: - BLT_DEBUG("Tree is too small!"); - break; - } + BLT_DEBUG("Crossover Failed."); errors++; new_pop.get_individuals().push_back(ind[first]); new_pop.get_individuals().push_back(ind[second]); @@ -153,7 +145,7 @@ int main() BLT_INFO("Post-Crossover:"); for (auto& tree : new_pop.for_each_tree()) { - auto f = tree.get_evaluation_value(nullptr); + auto f = tree.get_evaluation_value(); pos.push_back(f); BLT_TRACE(f); } diff --git a/tests/gp_test_6.cpp b/tests/gp_test_6.cpp index a3955e6..4be7b28 100644 --- a/tests/gp_test_6.cpp +++ b/tests/gp_test_6.cpp @@ -38,11 +38,9 @@ #include #include -static constexpr long SEED = 41912; +static const auto SEED_FUNC = [] { return std::random_device()(); }; - -blt::gp::type_provider type_system; -blt::gp::gp_program program(type_system, SEED); // NOLINT +blt::gp::gp_program program(SEED_FUNC); // NOLINT blt::gp::operation_t add([](float a, float b) { return a + b; }, "add"); // 0 blt::gp::operation_t sub([](float a, float b) { return a - b; }, "sub"); // 1 @@ -70,15 +68,12 @@ auto lit = blt::gp::operation_t([]() { */ int main() { - type_system.register_type(); - type_system.register_type(); - - blt::gp::operator_builder builder{type_system}; + blt::gp::operator_builder builder{}; program.set_operations(builder.build(add, sub, mul, pro_div, op_if, eq_f, eq_b, lt, gt, op_and, op_or, op_xor, op_not, lit)); blt::gp::ramped_half_initializer_t pop_init; - auto pop = pop_init.generate(blt::gp::initializer_arguments{program, type_system.get_type().id(), 500, 3, 10}); + auto pop = pop_init.generate(blt::gp::initializer_arguments{program, program.get_typesystem().get_type().id(), 500, 3, 10}); blt::gp::population_t new_pop; blt::gp::mutation_t mutator; @@ -90,19 +85,22 @@ int main() BLT_INFO("Pre-Mutation:"); for (auto& tree : pop.for_each_tree()) { - auto f = tree.get_evaluation_value(nullptr); + auto f = tree.get_evaluation_value(); pre.push_back(f); BLT_TRACE(f); } BLT_INFO("Mutation:"); for (auto& tree : pop.for_each_tree()) { - new_pop.get_individuals().emplace_back(mutator.apply(program, tree)); + blt::gp::tree_t tree_out{program}; + tree_out.copy_fast(tree); + mutator.apply(program, tree, tree_out); + new_pop.get_individuals().emplace_back(std::move(tree_out)); } BLT_INFO("Post-Mutation"); for (auto& tree : new_pop.for_each_tree()) { - auto f = tree.get_evaluation_value(nullptr); + auto f = tree.get_evaluation_value(); pos.push_back(f); BLT_TRACE(f); } diff --git a/tests/gp_test_7.cpp b/tests/gp_test_7.cpp index 25e9ad1..183256e 100644 --- a/tests/gp_test_7.cpp +++ b/tests/gp_test_7.cpp @@ -19,12 +19,11 @@ #include #include -static constexpr long SEED = 41912; +static const auto SEED_FUNC = [] { return std::random_device()(); }; blt::gp::prog_config_t config = blt::gp::prog_config_t().set_elite_count(2); -blt::gp::type_provider type_system; -blt::gp::gp_program program(type_system, SEED, config); // NOLINT +blt::gp::gp_program program(SEED_FUNC, config); // NOLINT std::array result_container; blt::gp::operation_t add([](float a, float b) { return a + b; }, "add"); // 0 @@ -59,7 +58,7 @@ void print_best() auto& tree = v.tree; auto size = tree.get_values().size(); BLT_TRACE("%lf [index %ld] (fitness: %lf, raw: %lf) (depth: %ld) (size: t: %ld u: %ld r: %ld) filled: %f%%", - tree.get_evaluation_value(nullptr), i, v.fitness.adjusted_fitness, v.fitness.raw_fitness, + tree.get_evaluation_value(), i, v.fitness.adjusted_fitness, v.fitness.raw_fitness, tree.get_depth(program), size.total_size_bytes, size.total_used_bytes, size.total_remaining_bytes, static_cast(size.total_used_bytes) / (size.total_size_bytes == 0 ? 1 : static_cast(size.total_size_bytes))); @@ -75,7 +74,7 @@ constexpr auto fitness_function = [](blt::gp::tree_t& current_tree, blt::gp::fit BLT_DEBUG("(depth: %ld) (blocks: %ld) (size: t: %ld m: %ld u: %ld r: %ld) filled: %f%%", current_tree.get_depth(program), size.blocks, size.total_size_bytes, size.total_no_meta_bytes, size.total_used_bytes, size.total_remaining_bytes, static_cast(size.total_used_bytes) / static_cast(size.total_no_meta_bytes));*/ - result_container[index] = current_tree.get_evaluation_value(nullptr); + result_container[index] = current_tree.get_evaluation_value(); fitness.raw_fitness = result_container[index] / 1000000000.0; fitness.standardized_fitness = fitness.raw_fitness; fitness.adjusted_fitness = 1.0 - (1.0 / (1.0 + fitness.raw_fitness)); @@ -86,14 +85,11 @@ constexpr auto fitness_function = [](blt::gp::tree_t& current_tree, blt::gp::fit */ int main() { - type_system.register_type(); - type_system.register_type(); - - blt::gp::operator_builder builder{type_system}; + blt::gp::operator_builder builder{}; program.set_operations(builder.build(add, sub, mul, pro_div, op_if, eq_f, eq_b, lt, gt, op_and, op_or, op_xor, op_not, lit)); auto sel = blt::gp::select_tournament_t{}; - program.generate_population(type_system.get_type().id(), fitness_function, sel, sel, sel); + program.generate_population(program.get_typesystem().get_type().id(), fitness_function, sel, sel, sel); while (!program.should_terminate()) { diff --git a/tests/order_tests.cpp b/tests/order_tests.cpp index 9db441b..3ff53ae 100644 --- a/tests/order_tests.cpp +++ b/tests/order_tests.cpp @@ -27,7 +27,6 @@ const blt::u64 SEED = std::random_device()(); //const blt::u64 SEED = 3495535167; blt::gp::random_t b_rand {SEED}; -blt::gp::type_provider type_system; struct context { @@ -82,18 +81,19 @@ auto basic_lit_b = blt::gp::operation_t([]() { void basic_test() { - blt::gp::gp_program program{type_system, SEED}; + blt::gp::gp_program program{SEED}; - blt::gp::operator_builder builder{type_system}; + blt::gp::operator_builder builder{}; program.set_operations(builder.build(basic_sub, basic_lit_f, basic_lit_b)); blt::gp::grow_generator_t gen; - blt::gp::generator_arguments args{program, type_system.get_type().id(), 1, 1}; - auto tree = gen.generate(args); + blt::gp::generator_arguments args{program, program.get_typesystem().get_type().id(), 1, 1}; + blt::gp::tree_t tree{program}; + gen.generate(tree, args); context ctx{&program}; - auto result = tree.get_evaluation_value(&ctx); + auto result = tree.get_evaluation_value(ctx); BLT_TRACE(result); BLT_ASSERT(result == -5.0f || result == 5.0f || result == 0.0f); tree.print(program, std::cout, true, true); @@ -103,9 +103,5 @@ int main() { BLT_INFO("Starting with seed %ld", SEED); - type_system.register_type(); - type_system.register_type(); - type_system.register_type(); - basic_test(); } \ No newline at end of file