thread
Brett 2024-07-10 22:00:28 -04:00
parent 602fef0c7c
commit 93dcf12b69
6 changed files with 70 additions and 35 deletions

View File

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

View File

@ -23,7 +23,7 @@
static constexpr long SEED = 41912;
blt::gp::prog_config_t config = blt::gp::prog_config_t().set_elite_count(0);
blt::gp::prog_config_t config = blt::gp::prog_config_t().set_elite_count(1);
blt::gp::type_provider type_system;
blt::gp::gp_program program(type_system, blt::gp::random_t{SEED}, config); // NOLINT
@ -53,13 +53,17 @@ blt::gp::operation_t lit([]() { // 13
void print_best()
{
BLT_TRACE("----{Current Gen: %ld}----", program.get_current_generation());
auto best = program.get_best<10>();
auto best = program.get_best_indexes<10>();
for (auto& v : best)
for (auto& i : best)
{
auto size = v.get().get_values().size();
BLT_TRACE("%lf (depth: %ld) (size: t: %ld m: %ld u: %ld r: %ld) filled: %f%%", v.get().get_evaluation_value<float>(nullptr),
v.get().get_depth(program), size.total_size_bytes, size.total_no_meta_bytes, size.total_used_bytes, size.total_remaining_bytes,
auto& v = program.get_current_pop().get_individuals()[i];
auto& tree = v.tree;
auto size = tree.get_values().size();
BLT_TRACE("%lf (fitness: %lf, raw: %lf) (depth: %ld) (blocks: %ld) (size: t: %ld m: %ld u: %ld r: %ld) filled: %f%%",
tree.get_evaluation_value<float>(nullptr), v.adjusted_fitness, v.raw_fitness,
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<double>(size.total_used_bytes) / static_cast<double>(size.total_no_meta_bytes));
}
//std::string small("--------------------------");
@ -101,10 +105,10 @@ int main()
while (!program.should_terminate())
{
program.evaluate_fitness([](blt::gp::tree_t& current_tree, decltype(result_container)& container, blt::size_t index) {
auto size = current_tree.get_values().size();
BLT_DEBUG("(depth: %ld) (size: t: %ld m: %ld u: %ld r: %ld) filled: %f%%",
current_tree.get_depth(program), size.total_size_bytes, size.total_no_meta_bytes, size.total_used_bytes,
size.total_remaining_bytes, static_cast<double>(size.total_used_bytes) / static_cast<double>(size.total_no_meta_bytes));
/*auto size = current_tree.get_values().size();
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<double>(size.total_used_bytes) / static_cast<double>(size.total_no_meta_bytes));*/
container[index] = current_tree.get_evaluation_value<float>(nullptr);
return container[index];
}, result_container);

View File

@ -277,15 +277,18 @@ namespace blt::gp
* NOTE: 0 is considered the best, in terms of standardized and adjusted fitness
*/
template<typename Container, typename Callable>
void evaluate_fitness(Callable&& fitness_function, Container& result_storage)
void evaluate_fitness(Callable&& fitness_function, Container& result_storage, bool larger_better = true)
{
for (const auto& ind : blt::enumerate(current_pop.get_individuals()))
ind.second.raw_fitness = static_cast<double>(fitness_function(ind.second.tree, result_storage, ind.first));
for (const auto& ind : blt::enumerate(current_pop.get_individuals()))
ind.second.raw_fitness = static_cast<double>(fitness_function(ind.second.tree, result_storage, ind.first));
double min = 0;
double max = 0;
for (auto& ind : current_pop.get_individuals())
{
if (ind.raw_fitness < min)
min = ind.raw_fitness;
if (larger_better && ind.raw_fitness > max)
max = ind.raw_fitness;
}
double overall_fitness = 0;
@ -297,8 +300,13 @@ namespace blt::gp
auto diff = -min;
for (auto& ind : current_pop.get_individuals())
{
// make standardized fitness [0, +inf)
auto standardized_fitness = ind.raw_fitness + diff;
ind.adjusted_fitness = 1.0 / (1.0 + standardized_fitness);
BLT_WARN(standardized_fitness);
if (larger_better)
standardized_fitness = (max + diff) - standardized_fitness;
BLT_WARN(standardized_fitness);
ind.adjusted_fitness = (1.0 / (1.0 + standardized_fitness));
if (ind.adjusted_fitness > worst_fitness)
{
@ -325,6 +333,11 @@ namespace blt::gp
current_generation++;
}
inline auto& get_current_pop()
{
return current_pop;
}
template<blt::size_t size>
std::array<blt::size_t, size> get_best_indexes()
{

View File

@ -50,13 +50,34 @@ namespace blt::gp
if (config.elites > 0)
{
std::vector<std::pair<std::size_t, double>> values;
for (blt::size_t i = 0; i < config.elites; i++)
values.emplace_back(i, current_pop.get_individuals()[i].adjusted_fitness);
for (auto& ind : current_pop.get_individuals())
for (const auto& ind : blt::enumerate(current_pop.get_individuals()))
{
blt::i64 largest = -1;
double largest_fit = 0;
for (blt::size_t i = 0; i < config.elites; i++)
{
BLT_INFO("%lf < %lf? // %lf", ind.second.adjusted_fitness, values[i].second, ind.second.raw_fitness);
if (ind.second.adjusted_fitness < values[i].second && values[i].second > largest_fit)
{
largest = static_cast<blt::i64>(i);
largest_fit = values[i].second;
}
}
if (largest > 0)
{
BLT_INFO("%ld %lf", largest, largest_fit);
values[largest] = {ind.first, ind.second.adjusted_fitness};
}
}
for (blt::size_t i = 0; i < config.elites; i++)
{
BLT_DEBUG("%lf %lf", values[i].second, current_pop.get_individuals()[values[i].first].tree.get_evaluation_value<float>(nullptr));
next_pop.get_individuals().push_back(current_pop.get_individuals()[values[i].first]);
}
}

View File

@ -42,6 +42,7 @@ namespace blt::gp
blt::size_t total_used_bytes = 0;
blt::size_t total_remaining_bytes = 0;
blt::size_t total_no_meta_bytes = 0;
blt::size_t blocks = 0;
};
@ -78,9 +79,11 @@ namespace blt::gp
head->metadata.offset -= TYPE_SIZE;
if (head->used_bytes_in_block() == 0)
{
auto ptr = head;
auto old = head;
head = head->metadata.prev;
std::free(ptr);
if (head != nullptr)
head->metadata.next = nullptr;
std::free(old);
}
return t;
}
@ -142,7 +145,10 @@ namespace blt::gp
bytes -= head->used_bytes_in_block();
auto old = head;
head = head->metadata.prev;
free(old);
// required to prevent silly memory :3
if (head != nullptr)
head->metadata.next = nullptr;
std::free(old);
if (diff == 0)
break;
} else
@ -184,13 +190,14 @@ namespace blt::gp
[[nodiscard]] size_data_t size()
{
size_data_t size_data;
auto next = head;
auto* next = head;
while (next != nullptr)
{
size_data.total_size_bytes += next->metadata.size;
size_data.total_no_meta_bytes += next->storage_size();
size_data.total_remaining_bytes += next->remaining_bytes_in_block();
size_data.total_used_bytes += next->used_bytes_in_block();
size_data.blocks++;
next = next->metadata.next;
}
return size_data;
@ -325,7 +332,7 @@ namespace blt::gp
template<typename T>
void push_block_for()
{
push_block(std::max(PAGE_SIZE, to_nearest_page_size(sizeof(T))));
push_block(aligned_size<T>());
}
void push_block(blt::size_t size)
@ -349,16 +356,6 @@ namespace blt::gp
static block* allocate_block(blt::size_t bytes)
{
#if BLT_DEBUG_LEVEL > 0
if (bytes > 32000)
{
BLT_WARN("Size too big!");
std::abort();
}
#endif
#if BLT_DEBUG_LEVEL > 2
BLT_DEBUG("Allocating bytes %ld", bytes);
#endif
auto size = to_nearest_page_size(bytes);
auto* data = std::aligned_alloc(PAGE_SIZE, size);
new(data) block{size};

@ -1 +1 @@
Subproject commit b6048ed39c9f34a4480f2a99c5d83817d3ccf1bf
Subproject commit 4de3aeb87c78a13f8e493e48477220084610c076