blt-gp/src/generators.cpp

126 lines
4.4 KiB
C++
Raw Normal View History

2024-06-02 13:38:24 -04:00
/*
* <Short Description>
* Copyright (C) 2024 Brett Terpstra
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
2024-06-21 22:04:57 -04:00
*/
#include <blt/gp/generators.h>
2024-06-23 14:13:50 -04:00
#include <blt/gp/program.h>
#include <stack>
2024-06-21 22:04:57 -04:00
namespace blt::gp
{
2024-06-23 14:13:50 -04:00
struct stack
{
blt::gp::operator_id id;
blt::size_t depth;
};
2024-06-24 21:56:51 -04:00
inline std::stack<stack> get_initial_stack(gp_program& program)
2024-06-23 14:13:50 -04:00
{
std::stack<stack> tree_generator;
auto& system = program.get_typesystem();
// select a type which has a non-empty set of non-terminals
type base_type;
do
{
base_type = system.select_type(program.get_random());
} while (program.get_type_non_terminals(base_type.id()).empty());
2024-06-23 14:13:50 -04:00
2024-06-24 21:56:51 -04:00
tree_generator.push(stack{program.select_non_terminal(base_type.id()), 1});
2024-06-23 14:13:50 -04:00
return tree_generator;
}
template<typename Func>
2024-06-24 21:56:51 -04:00
inline tree_t create_tree(Func&& perChild, gp_program& program)
2024-06-21 22:04:57 -04:00
{
2024-06-24 21:56:51 -04:00
std::stack<stack> tree_generator = get_initial_stack(program);
blt::size_t max_depth = 0;
2024-06-21 22:04:57 -04:00
tree_t tree;
2024-06-23 14:13:50 -04:00
while (!tree_generator.empty())
{
2024-06-24 21:56:51 -04:00
auto top = tree_generator.top();
tree_generator.pop();
tree.get_operations().push_back({top.id, static_cast<blt::u16>(top.depth)});
max_depth = std::max(max_depth, top.depth);
if (program.is_static(top.id))
{
program.get_operation(top.id)(nullptr, tree.get_values());
continue;
}
for (const auto& child : program.get_argument_types(top.id))
{
std::forward<Func>(perChild)(program, tree_generator, child, top.depth + 1);
}
2024-06-23 14:13:50 -04:00
}
2024-06-24 21:56:51 -04:00
tree.setDepth(max_depth);
2024-06-21 22:04:57 -04:00
return tree;
}
2024-06-23 14:13:50 -04:00
tree_t grow_generator_t::generate(gp_program& program, blt::size_t min_depth, blt::size_t max_depth)
{
2024-06-24 21:56:51 -04:00
return create_tree([min_depth, max_depth](gp_program& program, std::stack<stack>& tree_generator, const type& type, blt::size_t new_depth) {
if (new_depth >= max_depth)
{
tree_generator.push({program.select_terminal(type.id()), new_depth});
return;
}
if (program.choice() || new_depth < min_depth)
tree_generator.push({program.select_non_terminal(type.id()), new_depth});
else
tree_generator.push({program.select_terminal(type.id()), new_depth});
}, program);
2024-06-23 14:13:50 -04:00
}
2024-06-24 21:56:51 -04:00
tree_t full_generator_t::generate(gp_program& program, blt::size_t, blt::size_t max_depth)
2024-06-21 22:04:57 -04:00
{
2024-06-24 21:56:51 -04:00
return create_tree([max_depth](gp_program& program, std::stack<stack>& tree_generator, const type& type, blt::size_t new_depth) {
if (new_depth >= max_depth)
{
tree_generator.push({program.select_terminal(type.id()), new_depth});
return;
}
tree_generator.push({program.select_non_terminal(type.id()), new_depth});
}, program);
}
population_t grow_initializer_t::generate(gp_program& program, blt::size_t size, blt::size_t min_depth, blt::size_t max_depth)
{
return population_t();
}
population_t full_initializer_t::generate(gp_program& program, blt::size_t size, blt::size_t min_depth, blt::size_t max_depth)
{
return population_t();
}
population_t half_half_initializer_t::generate(gp_program& program, blt::size_t size, blt::size_t min_depth, blt::size_t max_depth)
{
return population_t();
}
population_t ramped_half_initializer_t::generate(gp_program& program, blt::size_t size, blt::size_t min_depth, blt::size_t max_depth)
{
return population_t();
2024-06-21 22:04:57 -04:00
}
}