partial transfer to types
parent
30372f1c71
commit
ab67289745
|
@ -27,7 +27,7 @@ macro(compile_options target_name)
|
|||
sanitizers(${target_name})
|
||||
endmacro()
|
||||
|
||||
project(blt-gp VERSION 0.5.30)
|
||||
project(blt-gp VERSION 0.5.31)
|
||||
|
||||
include(CTest)
|
||||
|
||||
|
|
|
@ -79,7 +79,7 @@ namespace blt::gp::example
|
|||
BLT_DEBUG("Begin Generation Loop");
|
||||
while (!program.should_terminate())
|
||||
{
|
||||
BLT_TRACE("------------{Begin Generation %ld}------------", program.get_current_generation());
|
||||
BLT_TRACE("------------\\{Begin Generation {}}------------", program.get_current_generation());
|
||||
BLT_TRACE("Creating next generation");
|
||||
program.create_next_generation();
|
||||
BLT_TRACE("Move to next generation");
|
||||
|
@ -87,7 +87,7 @@ namespace blt::gp::example
|
|||
BLT_TRACE("Evaluate Fitness");
|
||||
program.evaluate_fitness();
|
||||
auto& stats = program.get_population_stats();
|
||||
BLT_TRACE("Avg Fit: %lf, Best Fit: %lf, Worst Fit: %lf, Overall Fit: %lf",
|
||||
BLT_TRACE("Avg Fit: {}, Best Fit: {}, Worst Fit: {}, Overall Fit: {}",
|
||||
stats.average_fitness.load(std::memory_order_relaxed), stats.best_fitness.load(std::memory_order_relaxed),
|
||||
stats.worst_fitness.load(std::memory_order_relaxed), stats.overall_fitness.load(std::memory_order_relaxed));
|
||||
BLT_TRACE("----------------------------------------------");
|
||||
|
|
|
@ -53,6 +53,8 @@ namespace blt::gp
|
|||
|
||||
struct multi_operation_tree_manipulator_t;
|
||||
|
||||
struct subtree_point_t;
|
||||
|
||||
class tree_t;
|
||||
|
||||
struct individual_t;
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
#ifndef BLT_GP_TRANSFORMERS_H
|
||||
#define BLT_GP_TRANSFORMERS_H
|
||||
|
||||
#include <blt/std/utility.h>
|
||||
#include <blt/gp/fwdecl.h>
|
||||
#include <blt/gp/tree.h>
|
||||
#include <blt/gp/generators.h>
|
||||
|
@ -120,8 +119,8 @@ namespace blt::gp
|
|||
public:
|
||||
struct crossover_point_t
|
||||
{
|
||||
tree_t::subtree_point_t p1_crossover_point;
|
||||
tree_t::subtree_point_t p2_crossover_point;
|
||||
subtree_point_t p1_crossover_point;
|
||||
subtree_point_t p2_crossover_point;
|
||||
};
|
||||
|
||||
|
||||
|
@ -152,7 +151,7 @@ namespace blt::gp
|
|||
~subtree_crossover_t() override = default;
|
||||
|
||||
protected:
|
||||
[[nodiscard]] std::optional<tree_t::subtree_point_t> get_point_traverse_retry(const tree_t& t, std::optional<type_id> type) const;
|
||||
[[nodiscard]] std::optional<subtree_point_t> get_point_traverse_retry(const tree_t& t, std::optional<type_id> type) const;
|
||||
};
|
||||
|
||||
class one_point_crossover_t : public crossover_t
|
||||
|
@ -204,7 +203,7 @@ namespace blt::gp
|
|||
virtual bool apply(gp_program& program, const tree_t& p, tree_t& c);
|
||||
|
||||
// returns the point after the mutation
|
||||
size_t mutate_point(gp_program& program, tree_t& c, tree_t::subtree_point_t node) const;
|
||||
size_t mutate_point(gp_program& program, tree_t& c, subtree_point_t node) const;
|
||||
|
||||
virtual ~mutation_t() = default;
|
||||
|
||||
|
|
|
@ -29,8 +29,6 @@
|
|||
#include <utility>
|
||||
#include <stack>
|
||||
|
||||
#include "program.h"
|
||||
|
||||
namespace blt::gp
|
||||
{
|
||||
namespace detail
|
||||
|
@ -234,6 +232,16 @@ namespace blt::gp
|
|||
|
||||
struct subtree_point_t
|
||||
{
|
||||
subtree_point_t() = default;
|
||||
|
||||
explicit subtree_point_t(const size_t point): point(point), info(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
explicit subtree_point_t(const ssize_t point): point(static_cast<size_t>(point)), info(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
subtree_point_t(const size_t point, const operator_info_t& info): point(point), info(&info) // NOLINT
|
||||
{
|
||||
}
|
||||
|
@ -254,13 +262,17 @@ namespace blt::gp
|
|||
|
||||
[[nodiscard]] const operator_info_t& get_info() const
|
||||
{
|
||||
#if BLT_DEBUG_LEVEL > 0
|
||||
if (info == nullptr)
|
||||
throw std::runtime_error(
|
||||
"Invalid subtree point, operator info was null! "
|
||||
"(Point probably created with passthrough intentions or operator info was not available, "
|
||||
"please manually acquire info from the program!)");
|
||||
#endif
|
||||
return *info;
|
||||
}
|
||||
|
||||
[[nodiscard]] type_id get_type() const
|
||||
{
|
||||
return info->return_type;
|
||||
}
|
||||
[[nodiscard]] type_id get_type() const;
|
||||
|
||||
size_t point;
|
||||
const operator_info_t* info;
|
||||
|
@ -316,7 +328,7 @@ namespace blt::gp
|
|||
* @param operators vector for storing subtree operators
|
||||
* @param stack stack for storing subtree values
|
||||
*/
|
||||
void copy_subtree(const subtree_point_t point, tracked_vector<op_container_t>& operators, stack_allocator& stack) const;
|
||||
void copy_subtree(subtree_point_t point, tracked_vector<op_container_t>& operators, stack_allocator& stack) const;
|
||||
|
||||
void copy_subtree(subtree_point_t point, ptrdiff_t extent, tree_t& out_tree) const;
|
||||
|
||||
|
@ -376,19 +388,10 @@ namespace blt::gp
|
|||
*/
|
||||
ptrdiff_t insert_subtree(subtree_point_t point, tree_t& other_tree) const;
|
||||
|
||||
/**
|
||||
* temporarily moves the last bytes amount of data from the current stack. this can be useful for if you are going to do a lot
|
||||
* of consecutive operations on the tree as this will avoid extra copy + reinsert.
|
||||
* The object returned by this function will automatically move the data back in when it goes out of scope.
|
||||
* @param operator_index operator index to move from. this is inclusive
|
||||
*/
|
||||
void temporary_move(const size_t)
|
||||
{
|
||||
// return obt_move_t{*this, operator_index};
|
||||
}
|
||||
|
||||
void modify_operator(size_t point, operator_id new_id, std::optional<type_id> return_type = {}) const;
|
||||
|
||||
void swap_operators(size_t point, tree_t& other_tree, size_t other_point) const;
|
||||
|
||||
tree_t* tree;
|
||||
};
|
||||
|
||||
|
@ -504,6 +507,11 @@ namespace blt::gp
|
|||
|
||||
tree_t& operator=(tree_t&& move) = default;
|
||||
|
||||
tree_manipulator_t manipulate()
|
||||
{
|
||||
return tree_manipulator_t{*this};
|
||||
}
|
||||
|
||||
void clear(gp_program& program);
|
||||
|
||||
void insert_operator(size_t index, const op_container_t& container);
|
||||
|
|
|
@ -80,7 +80,7 @@ namespace blt::gp
|
|||
if (!point)
|
||||
return false;
|
||||
|
||||
c1.swap_subtrees(point->p1_crossover_point, c2, point->p2_crossover_point);
|
||||
c1.manipulate().easy_manipulator().swap_subtrees(point->p1_crossover_point, c2, point->p2_crossover_point);
|
||||
|
||||
#if BLT_DEBUG_LEVEL >= 2
|
||||
if (!c1.check(detail::debug::context_ptr) || !c2.check(detail::debug::context_ptr))
|
||||
|
@ -94,7 +94,7 @@ namespace blt::gp
|
|||
const tree_t& c2) const
|
||||
{
|
||||
const auto first = c1.select_subtree(config.terminal_chance);
|
||||
const auto second = c2.select_subtree(first.type, config.max_crossover_tries, config.terminal_chance);
|
||||
const auto second = c2.select_subtree(first.get_type(), config.max_crossover_tries, config.terminal_chance);
|
||||
|
||||
if (!second)
|
||||
return {};
|
||||
|
@ -108,13 +108,13 @@ namespace blt::gp
|
|||
auto c1_point_o = get_point_traverse_retry(c1, {});
|
||||
if (!c1_point_o)
|
||||
return {};
|
||||
const auto c2_point_o = get_point_traverse_retry(c2, c1_point_o->type);
|
||||
const auto c2_point_o = get_point_traverse_retry(c2, c1_point_o->get_type());
|
||||
if (!c2_point_o)
|
||||
return {};
|
||||
return {{*c1_point_o, *c2_point_o}};
|
||||
}
|
||||
|
||||
std::optional<tree_t::subtree_point_t> subtree_crossover_t::get_point_traverse_retry(const tree_t& t, const std::optional<type_id> type) const
|
||||
std::optional<subtree_point_t> subtree_crossover_t::get_point_traverse_retry(const tree_t& t, const std::optional<type_id> type) const
|
||||
{
|
||||
if (type)
|
||||
return t.select_subtree_traverse(*type, config.max_crossover_tries, config.terminal_chance, config.depth_multiplier);
|
||||
|
@ -126,25 +126,25 @@ namespace blt::gp
|
|||
// if (p1.size() < config.min_tree_size || p2.size() < config.min_tree_size)
|
||||
// return false;
|
||||
|
||||
tree_t::subtree_point_t point1, point2; // NOLINT
|
||||
subtree_point_t point1, point2; // NOLINT
|
||||
if (config.traverse)
|
||||
{
|
||||
point1 = p1.select_subtree_traverse(config.terminal_chance, config.depth_multiplier);
|
||||
if (const auto val = p2.select_subtree_traverse(point1.type, config.max_crossover_tries, config.terminal_chance, config.depth_multiplier))
|
||||
if (const auto val = p2.select_subtree_traverse(point1.get_type(), config.max_crossover_tries, config.terminal_chance, config.depth_multiplier))
|
||||
point2 = *val;
|
||||
else
|
||||
return false;
|
||||
} else
|
||||
{
|
||||
point1 = p1.select_subtree(config.terminal_chance);
|
||||
if (const auto val = p2.select_subtree(point1.type, config.max_crossover_tries, config.terminal_chance))
|
||||
if (const auto val = p2.select_subtree(point1.get_type(), config.max_crossover_tries, config.terminal_chance))
|
||||
point2 = *val;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto& p1_operator = p1.get_operator(point1.pos);
|
||||
const auto& p2_operator = p2.get_operator(point2.pos);
|
||||
const auto& p1_operator = p1.get_operator(point1.get_point());
|
||||
const auto& p2_operator = p2.get_operator(point2.get_point());
|
||||
|
||||
const auto& p1_info = program.get_operator_info(p1_operator.id());
|
||||
const auto& p2_info = program.get_operator_info(p2_operator.id());
|
||||
|
@ -163,8 +163,8 @@ namespace blt::gp
|
|||
|
||||
thread_local struct type_resolver_t
|
||||
{
|
||||
tracked_vector<tree_t::child_t> children_data_p1;
|
||||
tracked_vector<tree_t::child_t> children_data_p2;
|
||||
tracked_vector<child_t> children_data_p1;
|
||||
tracked_vector<child_t> children_data_p2;
|
||||
hashmap_t<type_id, std::vector<size_t>> missing_p1_types;
|
||||
hashmap_t<type_id, std::vector<size_t>> missing_p2_types;
|
||||
hashset_t<size_t> correct_types;
|
||||
|
@ -231,7 +231,7 @@ namespace blt::gp
|
|||
return correct_types.contains(index) || p2_correct_types.contains(index);
|
||||
}
|
||||
|
||||
void clear()
|
||||
void clear(gp_program& program)
|
||||
{
|
||||
children_data_p1.clear();
|
||||
children_data_p2.clear();
|
||||
|
@ -249,7 +249,7 @@ namespace blt::gp
|
|||
v.clear();
|
||||
}
|
||||
} resolver;
|
||||
resolver.clear();
|
||||
resolver.clear(program);
|
||||
|
||||
auto min_size = std::min(p1_info.argument_types.size(), p2_info.argument_types.size());
|
||||
|
||||
|
@ -321,19 +321,19 @@ namespace blt::gp
|
|||
}
|
||||
|
||||
// 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());
|
||||
p1.find_child_extends(resolver.children_data_p1, point1.get_point(), p1_info.argument_types.size());
|
||||
p2.find_child_extends(resolver.children_data_p2, point2.get_point(), p2_info.argument_types.size());
|
||||
|
||||
for (const auto& [index1, index2] : resolver.p1_reorder_types)
|
||||
{
|
||||
BLT_DEBUG("Reordering in C1: {} -> {}", index1, index2);
|
||||
c1.swap_subtrees(resolver.children_data_p1[index1], c1, resolver.children_data_p1[index2]);
|
||||
c1.manipulate().easy_manipulator().swap_subtrees(resolver.children_data_p1[index1], c1, resolver.children_data_p1[index2]);
|
||||
}
|
||||
|
||||
for (const auto& [index1, index2] : resolver.p2_reorder_types)
|
||||
{
|
||||
BLT_DEBUG("Reordering in C2: {} -> {}", index1, index2);
|
||||
c2.swap_subtrees(resolver.children_data_p2[index1], c2, resolver.children_data_p2[index2]);
|
||||
c2.manipulate().easy_manipulator().swap_subtrees(resolver.children_data_p2[index1], c2, resolver.children_data_p2[index2]);
|
||||
}
|
||||
|
||||
auto c1_insert = resolver.children_data_p1.back().end;
|
||||
|
@ -342,14 +342,14 @@ namespace blt::gp
|
|||
for (const auto& [p1_index, p2_index] : resolver.swap_types)
|
||||
{
|
||||
if (p1_index < p1_info.argument_types.size() && p2_index < p2_info.argument_types.size())
|
||||
c1.swap_subtrees(resolver.children_data_p1[p1_index], c2, resolver.children_data_p2[p2_index]);
|
||||
c1.manipulate().easy_manipulator().swap_subtrees(resolver.children_data_p1[p1_index], c2, resolver.children_data_p2[p2_index]);
|
||||
else if (p1_index < p1_info.argument_types.size() && p2_index >= p2_info.argument_types.size())
|
||||
{
|
||||
BLT_TRACE("(P1 IS UNDER!) Trying to swap P1 {} for P2 {} (Sizes: P1: {} P2: {})", p1_index, p2_index, p1_info.argument_types.size(), p2_info.argument_types.size());
|
||||
BLT_TRACE("Inserting into P2 from P1!");
|
||||
c1.copy_subtree(resolver.children_data_p1[p1_index], resolver.temp_tree);
|
||||
c1.delete_subtree(resolver.children_data_p1[p1_index]);
|
||||
c2_insert = c2.insert_subtree(tree_t::subtree_point_t{c1_insert}, resolver.temp_tree);
|
||||
c1.manipulate().easy_manipulator().copy_subtree(resolver.children_data_p1[p1_index], resolver.temp_trees[0]);
|
||||
c1.manipulate().easy_manipulator().delete_subtree(resolver.children_data_p1[p1_index]);
|
||||
c2_insert = c2.manipulate().easy_manipulator().insert_subtree(subtree_point_t{c1_insert}, resolver.temp_trees[0]);
|
||||
} else if (p2_index < p2_info.argument_types.size() && p1_index >= p1_info.argument_types.size())
|
||||
{
|
||||
BLT_TRACE("(P2 IS UNDER!) Trying to swap P1 {} for P2 {} (Sizes: P1: {} P2: {})", p1_index, p2_index, p1_info.argument_types.size(), p2_info.argument_types.size());
|
||||
|
@ -360,8 +360,8 @@ namespace blt::gp
|
|||
}
|
||||
|
||||
|
||||
c1.modify_operator(point1.pos, p2_operator.id(), p2_info.return_type);
|
||||
c2.modify_operator(point2.pos, p1_operator.id(), p1_info.return_type);
|
||||
c1.manipulate().easy_manipulator().modify_operator(point1.get_point(), p2_operator.id(), p2_info.return_type);
|
||||
c2.manipulate().easy_manipulator().modify_operator(point2.get_point(), p1_operator.id(), p1_info.return_type);
|
||||
|
||||
#if BLT_DEBUG_LEVEL >= 2
|
||||
if (!c1.check(detail::debug::context_ptr) || !c2.check(detail::debug::context_ptr))
|
||||
|
@ -413,17 +413,17 @@ namespace blt::gp
|
|||
return true;
|
||||
}
|
||||
|
||||
size_t mutation_t::mutate_point(gp_program& program, tree_t& c, const tree_t::subtree_point_t node) const
|
||||
size_t mutation_t::mutate_point(gp_program& program, tree_t& c, const subtree_point_t node) const
|
||||
{
|
||||
auto& new_tree = tree_t::get_thread_local(program);
|
||||
#if BLT_DEBUG_LEVEL >= 2
|
||||
auto previous_size = new_tree.size();
|
||||
auto previous_bytes = new_tree.total_value_bytes();
|
||||
#endif
|
||||
config.generator.get().generate(new_tree, {program, node.type, config.replacement_min_depth, config.replacement_max_depth});
|
||||
config.generator.get().generate(new_tree, {program, node.get_type(), config.replacement_min_depth, config.replacement_max_depth});
|
||||
|
||||
#if BLT_DEBUG_LEVEL >= 2
|
||||
const auto old_op = c.get_operator(node.pos);
|
||||
const auto old_op = c.get_operator(node.get_point());
|
||||
if (!new_tree.check(detail::debug::context_ptr))
|
||||
{
|
||||
BLT_ERROR("Mutate point new tree check failed!");
|
||||
|
@ -434,11 +434,11 @@ namespace blt::gp
|
|||
}
|
||||
#endif
|
||||
|
||||
c.replace_subtree(node, new_tree);
|
||||
c.manipulate().easy_manipulator().replace_subtree(node, new_tree);
|
||||
|
||||
// this will check to make sure that the tree is in a correct and executable state. it requires that the evaluation is context free!
|
||||
#if BLT_DEBUG_LEVEL >= 2
|
||||
const auto new_op = c.get_operator(node.pos);
|
||||
const auto new_op = c.get_operator(node.get_point());
|
||||
if (!c.check(detail::debug::context_ptr))
|
||||
{
|
||||
print_mutate_stats();
|
||||
|
@ -450,7 +450,7 @@ namespace blt::gp
|
|||
#if defined(BLT_TRACK_ALLOCATIONS) || BLT_DEBUG_LEVEL >= 2
|
||||
++mutate_point_counter;
|
||||
#endif
|
||||
return node.pos + new_tree.size();
|
||||
return node.get_point() + new_tree.size();
|
||||
}
|
||||
|
||||
bool advanced_mutation_t::apply(gp_program& program, [[maybe_unused]] const tree_t& p, tree_t& c)
|
||||
|
@ -496,7 +496,7 @@ namespace blt::gp
|
|||
auto& replacement_func_info = program.get_operator_info(random_replacement);
|
||||
|
||||
// cache memory used for offset data.
|
||||
thread_local tracked_vector<tree_t::child_t> children_data;
|
||||
thread_local tracked_vector<child_t> children_data;
|
||||
children_data.clear();
|
||||
|
||||
c.find_child_extends(children_data, c_node, current_func_info.argument_types.size());
|
||||
|
@ -512,7 +512,7 @@ namespace blt::gp
|
|||
{program, val.id, config.replacement_min_depth, config.replacement_max_depth});
|
||||
|
||||
auto& [child_start, child_end] = children_data[children_data.size() - 1 - index];
|
||||
c.replace_subtree(c.subtree_from_point(child_start), child_end, tree);
|
||||
c.manipulate().easy_manipulator().replace_subtree(c.subtree_from_point(child_start), child_end, tree);
|
||||
|
||||
// shift over everybody after.
|
||||
if (index > 0)
|
||||
|
@ -537,7 +537,7 @@ namespace blt::gp
|
|||
{
|
||||
auto end_index = children_data[(current_func_info.argc.argc - replacement_func_info.argc.argc) - 1].end;
|
||||
auto start_index = children_data.begin()->start;
|
||||
c.delete_subtree(tree_t::subtree_point_t(start_index), end_index);
|
||||
c.manipulate().easy_manipulator().delete_subtree(subtree_point_t(start_index), end_index);
|
||||
}
|
||||
else if (current_func_info.argc.argc == replacement_func_info.argc.argc)
|
||||
{
|
||||
|
@ -561,11 +561,11 @@ namespace blt::gp
|
|||
program, replacement_func_info.argument_types[i].id, config.replacement_min_depth,
|
||||
config.replacement_max_depth
|
||||
});
|
||||
start_index = c.insert_subtree(tree_t::subtree_point_t(static_cast<ptrdiff_t>(start_index)), tree);
|
||||
start_index = c.manipulate().easy_manipulator().insert_subtree(subtree_point_t(static_cast<ptrdiff_t>(start_index)), tree);
|
||||
}
|
||||
}
|
||||
// now finally update the type.
|
||||
c.modify_operator(c_node, random_replacement, replacement_func_info.return_type);
|
||||
c.manipulate().easy_manipulator().modify_operator(c_node, random_replacement, replacement_func_info.return_type);
|
||||
}
|
||||
#if BLT_DEBUG_LEVEL >= 2
|
||||
if (!c.check(detail::debug::context_ptr))
|
||||
|
@ -636,7 +636,7 @@ namespace blt::gp
|
|||
program, replacement_func_info.argument_types[i].id, config.replacement_min_depth,
|
||||
config.replacement_max_depth
|
||||
});
|
||||
start_index = c.insert_subtree(tree_t::subtree_point_t(static_cast<ptrdiff_t>(start_index)), tree);
|
||||
start_index = c.manipulate().easy_manipulator().insert_subtree(subtree_point_t(static_cast<ptrdiff_t>(start_index)), tree);
|
||||
}
|
||||
start_index += size;
|
||||
// vals.copy_from(combined_ptr, for_bytes);
|
||||
|
@ -648,7 +648,7 @@ namespace blt::gp
|
|||
program, replacement_func_info.argument_types[i].id, config.replacement_min_depth,
|
||||
config.replacement_max_depth
|
||||
});
|
||||
start_index = c.insert_subtree(tree_t::subtree_point_t(static_cast<ptrdiff_t>(start_index)), tree);
|
||||
start_index = c.manipulate().easy_manipulator().insert_subtree(subtree_point_t(static_cast<ptrdiff_t>(start_index)), tree);
|
||||
}
|
||||
// vals.copy_from(combined_ptr + for_bytes, after_bytes);
|
||||
|
||||
|
@ -690,7 +690,7 @@ namespace blt::gp
|
|||
if (argument_index == -1ul)
|
||||
continue;
|
||||
|
||||
thread_local tracked_vector<tree_t::child_t> child_data;
|
||||
thread_local tracked_vector<child_t> child_data;
|
||||
child_data.clear();
|
||||
|
||||
c.find_child_extends(child_data, c_node, info.argument_types.size());
|
||||
|
@ -700,9 +700,9 @@ namespace blt::gp
|
|||
|
||||
thread_local tree_t child_tree{program};
|
||||
|
||||
c.copy_subtree(tree_t::subtree_point_t(child.start), child.end, child_tree);
|
||||
c.delete_subtree(tree_t::subtree_point_t(static_cast<ptrdiff_t>(c_node)));
|
||||
c.insert_subtree(tree_t::subtree_point_t(static_cast<ptrdiff_t>(c_node)), child_tree);
|
||||
c.manipulate().easy_manipulator().copy_subtree(subtree_point_t(child.start), child.end, child_tree);
|
||||
c.manipulate().easy_manipulator().delete_subtree(subtree_point_t(static_cast<ptrdiff_t>(c_node)));
|
||||
c.manipulate().easy_manipulator().insert_subtree(subtree_point_t(static_cast<ptrdiff_t>(c_node)), child_tree);
|
||||
child_tree.clear(program);
|
||||
|
||||
// auto for_bytes = c.total_value_bytes(child.start, child.end);
|
||||
|
@ -769,7 +769,7 @@ namespace blt::gp
|
|||
continue;
|
||||
const auto to_index = program.get_random().select(potential_indexes);
|
||||
|
||||
thread_local tracked_vector<tree_t::child_t> child_data;
|
||||
thread_local tracked_vector<child_t> child_data;
|
||||
child_data.clear();
|
||||
|
||||
c.find_child_extends(child_data, c_node, info.argument_types.size());
|
||||
|
@ -780,8 +780,8 @@ namespace blt::gp
|
|||
const auto& [to_start, to_end] = child_data[child_to_index];
|
||||
|
||||
thread_local tree_t copy_tree{program};
|
||||
c.copy_subtree(tree_t::subtree_point_t{from_start}, from_end, copy_tree);
|
||||
c.replace_subtree(tree_t::subtree_point_t{to_start}, to_end, copy_tree);
|
||||
c.manipulate().easy_manipulator().copy_subtree(subtree_point_t{from_start}, from_end, copy_tree);
|
||||
c.manipulate().easy_manipulator().replace_subtree(subtree_point_t{to_start}, to_end, copy_tree);
|
||||
copy_tree.clear(program);
|
||||
|
||||
#if BLT_DEBUG_LEVEL >= 2
|
||||
|
|
39
src/tree.cpp
39
src/tree.cpp
|
@ -125,13 +125,10 @@ namespace blt::gp
|
|||
create_indent(out, indent, pretty_print) << ")" << end_indent(pretty_print);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!pretty_print)
|
||||
out << " ";
|
||||
arguments_left.push(top - 1);
|
||||
break;
|
||||
}
|
||||
if (!pretty_print)
|
||||
out << " ";
|
||||
arguments_left.push(top - 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (!arguments_left.empty())
|
||||
|
@ -252,7 +249,7 @@ namespace blt::gp
|
|||
}
|
||||
|
||||
std::optional<subtree_point_t> tree_t::select_subtree_traverse(const type_id type, const u32 max_tries, const double terminal_chance,
|
||||
const double depth_multiplier) const
|
||||
const double depth_multiplier) const
|
||||
{
|
||||
for (u32 i = 0; i < max_tries; ++i)
|
||||
{
|
||||
|
@ -262,7 +259,8 @@ namespace blt::gp
|
|||
return {};
|
||||
}
|
||||
|
||||
void slow_tree_manipulator_t::copy_subtree(const subtree_point_t point, const ptrdiff_t extent, tracked_vector<op_container_t>& operators, stack_allocator& stack) const
|
||||
void slow_tree_manipulator_t::copy_subtree(const subtree_point_t point, const ptrdiff_t extent, tracked_vector<op_container_t>& operators,
|
||||
stack_allocator& stack) const
|
||||
{
|
||||
const auto point_begin_itr = tree->operations.begin() + point.get_spoint();
|
||||
const auto point_end_itr = tree->operations.begin() + extent;
|
||||
|
@ -310,7 +308,7 @@ namespace blt::gp
|
|||
|
||||
void slow_tree_manipulator_t::copy_subtree(const child_t subtree, tree_t& out_tree) const
|
||||
{
|
||||
copy_subtree(subtree_point_t{subtree.start, tree->m_program->get_operator_info(tree->operations[subtree.start].id())}, subtree.end, out_tree);
|
||||
copy_subtree(subtree_point_t{subtree.start}, subtree.end, out_tree);
|
||||
}
|
||||
|
||||
void slow_tree_manipulator_t::swap_subtrees(const child_t our_subtree, tree_t& other_tree, const child_t other_subtree) const
|
||||
|
@ -385,7 +383,7 @@ namespace blt::gp
|
|||
void slow_tree_manipulator_t::swap_subtrees(const subtree_point_t our_subtree, tree_t& other_tree, const subtree_point_t other_subtree) const
|
||||
{
|
||||
swap_subtrees(child_t{our_subtree.get_spoint(), tree->find_endpoint(our_subtree.get_spoint())}, other_tree,
|
||||
child_t{other_subtree.get_spoint(), tree->find_endpoint(other_subtree.get_spoint())});
|
||||
child_t{other_subtree.get_spoint(), other_tree.find_endpoint(other_subtree.get_spoint())});
|
||||
}
|
||||
|
||||
void slow_tree_manipulator_t::replace_subtree(const subtree_point_t point, const ptrdiff_t extent, const tree_t& other_tree) const
|
||||
|
@ -660,6 +658,17 @@ namespace blt::gp
|
|||
{
|
||||
}
|
||||
|
||||
type_id subtree_point_t::get_type() const
|
||||
{
|
||||
#if BLT_DEBUG_LEVEL > 0
|
||||
if (info == nullptr)
|
||||
throw std::runtime_error(
|
||||
"Invalid subtree point, operator info was null! (Point probably created with passthrough "
|
||||
"intentions or operator info was not available, please manually acquire type)");
|
||||
#endif
|
||||
return info->return_type;
|
||||
}
|
||||
|
||||
void single_operation_tree_manipulator_t::replace_subtree(tree_t& other_tree)
|
||||
{
|
||||
replace_subtree(other_tree.operations, other_tree.values);
|
||||
|
@ -667,7 +676,6 @@ namespace blt::gp
|
|||
|
||||
void single_operation_tree_manipulator_t::replace_subtree(tracked_vector<op_container_t>& operations, stack_allocator& stack)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void tree_t::copy_fast(const tree_t& copy)
|
||||
|
@ -877,13 +885,18 @@ namespace blt::gp
|
|||
{
|
||||
if (move_data.empty())
|
||||
{
|
||||
const size_t after_bytes = calculate_ephemeral_size(tree->operations.begin() + static_cast<ptrdiff_t>(point) + 1, tree->operations.end());
|
||||
const size_t after_bytes = calculate_ephemeral_size(tree->operations.begin() + static_cast<ptrdiff_t>(point) + 1,
|
||||
tree->operations.end());
|
||||
move_data.move(after_bytes);
|
||||
}
|
||||
tree->handle_operator_inserted(tree->operations[point]);
|
||||
}
|
||||
}
|
||||
|
||||
void slow_tree_manipulator_t::swap_operators(size_t point, tree_t& other_tree, size_t other_point) const
|
||||
{
|
||||
}
|
||||
|
||||
bool operator==(const tree_t& a, const tree_t& b)
|
||||
{
|
||||
if (a.operations.size() != b.operations.size())
|
||||
|
|
Loading…
Reference in New Issue