i think there is a jim nearby

thread
Brett 2024-06-30 21:44:45 -04:00
parent 5346a2c77a
commit 580d017d3c
6 changed files with 66 additions and 4 deletions

View File

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

View File

@ -50,6 +50,14 @@ namespace blt::gp
blt::u32 argc_context = 0;
};
struct config_t
{
// number of times crossover will try to pick a valid point in the tree. this is purely based on the return type of the operators
blt::u16 max_crossover_tries = 5;
// if we fail to find a point in the tree, should we search forward from the last point to the end of the operators?
bool should_crossover_try_forward = false;
};
struct operator_info
{
std::vector<type_id> argument_types;
@ -286,10 +294,16 @@ namespace blt::gp
{
storage = std::move(op);
}
[[nodiscard]] inline const config_t& get_config() const
{
return config;
}
private:
type_provider& system;
blt::gp::stack_allocator alloc;
config_t config;
operator_storage storage;

View File

@ -32,12 +32,13 @@ namespace blt::gp
struct op_container_t
{
op_container_t(detail::callable_t& func, detail::transfer_t& transfer, bool is_value):
func(func), transfer(transfer), is_value(is_value)
op_container_t(detail::callable_t& func, detail::transfer_t& transfer, operator_id id, bool is_value):
func(func), transfer(transfer), id(id), is_value(is_value)
{}
detail::callable_t& func;
detail::transfer_t& transfer;
operator_id id;
bool is_value;
};

View File

@ -65,6 +65,7 @@ namespace blt::gp
tree.get_operations().emplace_back(
info.function,
info.transfer,
top.id,
args.program.is_static(top.id));
max_depth = std::max(max_depth, top.depth);

View File

@ -16,14 +16,60 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include <blt/gp/transformers.h>
#include <blt/gp/program.h>
#include <random>
namespace blt::gp
{
blt::expected<crossover_t::result_t, crossover_t::error_t> crossover_t::apply(gp_program& program, const tree_t& p1, const tree_t& p2) // NOLINT
{
const auto& config = program.get_config();
result_t result{p1, p2};
auto& c1 = result.child1;
auto& c2 = result.child2;
auto& c1_ops = c1.get_operations();
auto& c2_ops = c2.get_operations();
std::uniform_int_distribution op_sel1(1ul, c1_ops.size() - 1);
std::uniform_int_distribution op_sel2(1ul, c2_ops.size() - 1);
blt::size_t crossover_point = op_sel1(program.get_random());
blt::size_t attempted_point = 0;
const auto& crossover_point_type = program.get_operator_info(c1_ops[crossover_point].id);
operator_info* attempted_point_type = nullptr;
blt::size_t counter = 0;
do
{
if (counter >= config.max_crossover_tries)
{
if (config.should_crossover_try_forward)
{
for (auto i = attempted_point + 1; i < c2_ops.size(); i++)
{
auto* info = &program.get_operator_info(c2_ops[i].id);
if (info->return_type == crossover_point_type.return_type)
{
attempted_point = i;
attempted_point_type = info;
break;
}
}
}
// should we try again over the whole tree? probably not.
return blt::unexpected(error_t::NO_VALID_TYPE);
} else
{
attempted_point = op_sel2(program.get_random());
attempted_point_type = &program.get_operator_info(c2_ops[attempted_point].id);
counter++;
}
} while (crossover_point_type.return_type != attempted_point_type->return_type);
const auto& found_point_type = *attempted_point_type;
return result;
}

View File

@ -44,7 +44,7 @@ namespace blt::gp
continue;
}
operation.func(context, values_process, value_stack);
operations_stack.emplace_back(empty_callable, operation.transfer, true);
operations_stack.emplace_back(empty_callable, operation.transfer, operation.id, true);
}
return results;