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) cmake_minimum_required(VERSION 3.25)
project(blt-gp VERSION 0.0.45) project(blt-gp VERSION 0.0.46)
include(CTest) include(CTest)

View File

@ -50,6 +50,14 @@ namespace blt::gp
blt::u32 argc_context = 0; 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 struct operator_info
{ {
std::vector<type_id> argument_types; std::vector<type_id> argument_types;
@ -287,9 +295,15 @@ namespace blt::gp
storage = std::move(op); storage = std::move(op);
} }
[[nodiscard]] inline const config_t& get_config() const
{
return config;
}
private: private:
type_provider& system; type_provider& system;
blt::gp::stack_allocator alloc; blt::gp::stack_allocator alloc;
config_t config;
operator_storage storage; operator_storage storage;

View File

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

View File

@ -65,6 +65,7 @@ namespace blt::gp
tree.get_operations().emplace_back( tree.get_operations().emplace_back(
info.function, info.function,
info.transfer, info.transfer,
top.id,
args.program.is_static(top.id)); args.program.is_static(top.id));
max_depth = std::max(max_depth, top.depth); 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/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
#include <blt/gp/transformers.h> #include <blt/gp/transformers.h>
#include <blt/gp/program.h>
#include <random>
namespace blt::gp 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 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}; 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; return result;
} }

View File

@ -44,7 +44,7 @@ namespace blt::gp
continue; continue;
} }
operation.func(context, values_process, value_stack); 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; return results;