cancerious copy consturctors and fun little tests
parent
68dad0f963
commit
dae1d8cf6a
|
@ -21,12 +21,13 @@
|
||||||
|
|
||||||
#include <blt/std/types.h>
|
#include <blt/std/types.h>
|
||||||
|
|
||||||
|
inline constexpr blt::i32 MIN_DEPTH = 3;
|
||||||
inline constexpr blt::i32 MAX_DEPTH = 12;
|
inline constexpr blt::i32 MAX_DEPTH = 12;
|
||||||
inline constexpr blt::i32 width = 256, height = 256;
|
inline constexpr blt::i32 width = 256, height = 256;
|
||||||
inline constexpr blt::i32 POPULATION_SIZE = 20;
|
inline constexpr blt::i32 POPULATION_SIZE = 20;
|
||||||
inline constexpr blt::i32 GEN_COUNT = 20;
|
inline constexpr blt::i32 GEN_COUNT = 20;
|
||||||
inline constexpr blt::i32 TOURNAMENT_SIZE = 3;
|
inline constexpr blt::i32 TOURNAMENT_SIZE = 3;
|
||||||
inline constexpr float CROSSOVER_RATE = 0.9;
|
inline constexpr float CROSSOVER_RATE = 0.9;
|
||||||
inline constexpr float MUTATION_RATE = 0.9;
|
inline constexpr float MUTATION_RATE = 0.1;
|
||||||
|
|
||||||
#endif //GP_IMAGE_TEST_CONFIG_H
|
#endif //GP_IMAGE_TEST_CONFIG_H
|
||||||
|
|
|
@ -244,8 +244,7 @@ inline static allowed_funcs<function_t> intersection_comp(const allowed_funcs<fu
|
||||||
|
|
||||||
// distribution from normality (DFN)
|
// distribution from normality (DFN)
|
||||||
float eval_DNF_SW(const image& img);
|
float eval_DNF_SW(const image& img);
|
||||||
|
float eval_DNF_SW_1(const image& img);
|
||||||
float eval_DNF_KS(const image& img);
|
|
||||||
|
|
||||||
//template<typename F>
|
//template<typename F>
|
||||||
//bool isNan(F f)
|
//bool isNan(F f)
|
||||||
|
|
|
@ -65,6 +65,8 @@ struct node
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
node(const node& copy);
|
||||||
|
|
||||||
static node* construct_random_tree(blt::size_t max_depth = MAX_DEPTH);
|
static node* construct_random_tree(blt::size_t max_depth = MAX_DEPTH);
|
||||||
|
|
||||||
void evaluate();
|
void evaluate();
|
||||||
|
|
|
@ -10,13 +10,13 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
const std::vector<double> large_c {
|
const std::vector<double> large_c{
|
||||||
0.139E100, 0.157E100, 0.175E100, 0.256E100, 0.344E100, 0.413E100, 0.503E100, 0.577E100,
|
0.139E100, 0.157E100, 0.175E100, 0.256E100, 0.344E100, 0.413E100, 0.503E100, 0.577E100,
|
||||||
0.614E100, 0.655E100, 0.954E100, 1.392E100, 1.557E100, 1.648E100, 1.690E100, 1.994E100,
|
0.614E100, 0.655E100, 0.954E100, 1.392E100, 1.557E100, 1.648E100, 1.690E100, 1.994E100,
|
||||||
2.174E100, 2.206E100, 3.245E100, 3.510E100, 3.571E100, 4.354E100, 4.980E100, 6.084E100,
|
2.174E100, 2.206E100, 3.245E100, 3.510E100, 3.571E100, 4.354E100, 4.980E100, 6.084E100,
|
||||||
8.351E100};
|
8.351E100};
|
||||||
|
|
||||||
const std::vector<double> normally_c {-0.4417998157703872,
|
const std::vector<double> normally_c{-0.4417998157703872,
|
||||||
-0.310841224215176,
|
-0.310841224215176,
|
||||||
-0.2544758389229413,
|
-0.2544758389229413,
|
||||||
-0.21509882047762266,
|
-0.21509882047762266,
|
||||||
|
@ -42,12 +42,15 @@ const std::vector<double> normally_c {-0.4417998157703872,
|
||||||
0.310841224215176,
|
0.310841224215176,
|
||||||
0.4417998157703872};
|
0.4417998157703872};
|
||||||
|
|
||||||
const std::vector<double> nearly_c {
|
const std::vector<double> nearly_c{
|
||||||
-0.44, -0.31, -0.25, -0.21, -0.18, -0.15, -0.12, -0.10, -0.08, -0.06, -0.04, -0.02,
|
-0.44, -0.31, -0.25, -0.21, -0.18, -0.15, -0.12, -0.10, -0.08, -0.06, -0.04, -0.02,
|
||||||
0.0, 0.02, 0.04, 0.06, 0.08, 0.10, 0.12, 0.15, 0.18, 0.21, 0.25, 0.31, 0.44};
|
0.0, 0.02, 0.04, 0.06, 0.08, 0.10, 0.12, 0.15, 0.18, 0.21, 0.25, 0.31, 0.44};
|
||||||
|
|
||||||
|
const auto runs = 500000;
|
||||||
|
|
||||||
#undef BLT_DEBUG
|
#undef BLT_DEBUG
|
||||||
#define BLT_DEBUG(...)
|
#define BLT_DEBUG(...)
|
||||||
|
|
||||||
void shapiro_test_local()
|
void shapiro_test_local()
|
||||||
{
|
{
|
||||||
auto normally = normally_c;
|
auto normally = normally_c;
|
||||||
|
@ -58,6 +61,9 @@ void shapiro_test_local()
|
||||||
std::sort(nearly.begin(), nearly.end());
|
std::sort(nearly.begin(), nearly.end());
|
||||||
std::sort(large.begin(), large.end());
|
std::sort(large.begin(), large.end());
|
||||||
|
|
||||||
|
BLT_START_INTERVAL("shapiro", "local_sorted");
|
||||||
|
for (size_t i = 0; i < runs; i++)
|
||||||
|
{
|
||||||
willbruh w1(normally);
|
willbruh w1(normally);
|
||||||
BLT_ASSERT(w1->estimate == 0.9999999999999999);
|
BLT_ASSERT(w1->estimate == 0.9999999999999999);
|
||||||
BLT_ASSERT(w1->p_value == 1.0);
|
BLT_ASSERT(w1->p_value == 1.0);
|
||||||
|
@ -72,6 +78,8 @@ void shapiro_test_local()
|
||||||
BLT_ASSERT(w3->estimate == 0.8346662753181684);
|
BLT_ASSERT(w3->estimate == 0.8346662753181684);
|
||||||
BLT_ASSERT(w3->p_value == 0.0009134904817755807);
|
BLT_ASSERT(w3->p_value == 0.0009134904817755807);
|
||||||
BLT_DEBUG("%f // %f", w3->estimate, w3->p_value);
|
BLT_DEBUG("%f // %f", w3->estimate, w3->p_value);
|
||||||
|
}
|
||||||
|
BLT_END_INTERVAL("shapiro", "local_sorted");
|
||||||
}
|
}
|
||||||
|
|
||||||
void shapiro_test_unsorted()
|
void shapiro_test_unsorted()
|
||||||
|
@ -80,6 +88,9 @@ void shapiro_test_unsorted()
|
||||||
auto nearly = nearly_c;
|
auto nearly = nearly_c;
|
||||||
auto large = large_c;
|
auto large = large_c;
|
||||||
|
|
||||||
|
BLT_START_INTERVAL("shapiro", "unsorted_mut");
|
||||||
|
for (int i = 0; i < runs; i++)
|
||||||
|
{
|
||||||
willbruh w1(willbert_unsorted(normally.data(), normally.size()));
|
willbruh w1(willbert_unsorted(normally.data(), normally.size()));
|
||||||
BLT_ASSERT(w1->estimate == 0.9999999999999999);
|
BLT_ASSERT(w1->estimate == 0.9999999999999999);
|
||||||
BLT_ASSERT(w1->p_value == 1.0);
|
BLT_ASSERT(w1->p_value == 1.0);
|
||||||
|
@ -94,6 +105,8 @@ void shapiro_test_unsorted()
|
||||||
BLT_ASSERT(w3->estimate == 0.8346662753181684);
|
BLT_ASSERT(w3->estimate == 0.8346662753181684);
|
||||||
BLT_ASSERT(w3->p_value == 0.0009134904817755807);
|
BLT_ASSERT(w3->p_value == 0.0009134904817755807);
|
||||||
BLT_DEBUG("%f // %f", w3->estimate, w3->p_value);
|
BLT_DEBUG("%f // %f", w3->estimate, w3->p_value);
|
||||||
|
}
|
||||||
|
BLT_END_INTERVAL("shapiro", "unsorted_mut");
|
||||||
}
|
}
|
||||||
|
|
||||||
void shapiro_test_copy()
|
void shapiro_test_copy()
|
||||||
|
@ -102,6 +115,9 @@ void shapiro_test_copy()
|
||||||
auto nearly = nearly_c;
|
auto nearly = nearly_c;
|
||||||
auto large = large_c;
|
auto large = large_c;
|
||||||
|
|
||||||
|
BLT_START_INTERVAL("shapiro", "copy");
|
||||||
|
for (int i = 0; i < runs; i++)
|
||||||
|
{
|
||||||
willbruh w1(willbert_unsorted_copy(normally.data(), normally.size()));
|
willbruh w1(willbert_unsorted_copy(normally.data(), normally.size()));
|
||||||
BLT_ASSERT(w1->estimate == 0.9999999999999999);
|
BLT_ASSERT(w1->estimate == 0.9999999999999999);
|
||||||
BLT_ASSERT(w1->p_value == 1.0);
|
BLT_ASSERT(w1->p_value == 1.0);
|
||||||
|
@ -116,22 +132,15 @@ void shapiro_test_copy()
|
||||||
BLT_ASSERT(w3->estimate == 0.8346662753181684);
|
BLT_ASSERT(w3->estimate == 0.8346662753181684);
|
||||||
BLT_ASSERT(w3->p_value == 0.0009134904817755807);
|
BLT_ASSERT(w3->p_value == 0.0009134904817755807);
|
||||||
BLT_DEBUG("%f // %f", w3->estimate, w3->p_value);
|
BLT_DEBUG("%f // %f", w3->estimate, w3->p_value);
|
||||||
|
}
|
||||||
|
BLT_END_INTERVAL("shapiro", "copy");
|
||||||
}
|
}
|
||||||
|
|
||||||
void shapiro_test_run()
|
void shapiro_test_run()
|
||||||
{
|
{
|
||||||
const auto runs = 500000;
|
|
||||||
BLT_START_INTERVAL("shapiro", "copy");
|
|
||||||
for (size_t i = 0; i < runs; i++)
|
|
||||||
shapiro_test_copy();
|
shapiro_test_copy();
|
||||||
BLT_END_INTERVAL("shapiro", "copy");
|
|
||||||
BLT_START_INTERVAL("shapiro", "unsorted_mut");
|
|
||||||
for (size_t i = 0; i < runs; i++)
|
|
||||||
shapiro_test_unsorted();
|
shapiro_test_unsorted();
|
||||||
BLT_END_INTERVAL("shapiro", "unsorted_mut");
|
|
||||||
BLT_START_INTERVAL("shapiro", "local_sorted");
|
|
||||||
for (size_t i = 0; i < runs; i++)
|
|
||||||
shapiro_test_local();
|
shapiro_test_local();
|
||||||
BLT_END_INTERVAL("shapiro", "local_sorted");
|
|
||||||
BLT_PRINT_PROFILE("shapiro");
|
BLT_PRINT_PROFILE("shapiro");
|
||||||
}
|
}
|
||||||
|
|
|
@ -281,8 +281,30 @@ float eval_DNF_SW(const image& img)
|
||||||
return static_cast<float>(total);
|
return static_cast<float>(total);
|
||||||
}
|
}
|
||||||
|
|
||||||
float eval_DNF_KS(const image& img)
|
float eval_DNF_SW_1(const image& img)
|
||||||
{
|
{
|
||||||
return 0;
|
std::vector<double> order(width * height);
|
||||||
|
|
||||||
|
for (const auto& v : img.getData())
|
||||||
|
order.push_back(v.magnitude());
|
||||||
|
|
||||||
|
std::sort(order.begin(), order.end());
|
||||||
|
|
||||||
|
blt::size_t len = width / 4;
|
||||||
|
blt::size_t current_pos = 0;
|
||||||
|
double total = 0;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
if (order.size() - current_pos < len)
|
||||||
|
{
|
||||||
|
len = order.size() - current_pos;
|
||||||
|
if (len <= 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
total += on_data(order.data() + current_pos, len);
|
||||||
|
current_pos += len;
|
||||||
|
}
|
||||||
|
|
||||||
|
return static_cast<float>(total);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
16
src/gp.cpp
16
src/gp.cpp
|
@ -148,7 +148,7 @@ node* node::construct_random_tree(blt::size_t max_depth)
|
||||||
if (front.second != current_depth)
|
if (front.second != current_depth)
|
||||||
current_depth++;
|
current_depth++;
|
||||||
|
|
||||||
if (choice(engine))
|
if (choice(engine) && current_depth >= MIN_DEPTH)
|
||||||
front.first->grow(front.second >= max_depth);
|
front.first->grow(front.second >= max_depth);
|
||||||
else
|
else
|
||||||
front.first->full(front.second >= max_depth);
|
front.first->full(front.second >= max_depth);
|
||||||
|
@ -192,3 +192,17 @@ void node::evaluate()
|
||||||
}
|
}
|
||||||
#undef FUNC_DEFINE
|
#undef FUNC_DEFINE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
node::node(const node& copy)
|
||||||
|
{
|
||||||
|
argc = copy.argc;
|
||||||
|
type = copy.type;
|
||||||
|
static_assert(sizeof(data_t) == sizeof(float) * 3 && "Uhhh something is wrong here!");
|
||||||
|
std::memcpy(data.data(), copy.data.data(), sizeof(data_t));
|
||||||
|
for (blt::size_t i = 0; i < argc; i++)
|
||||||
|
{
|
||||||
|
sub_nodes[i] = node_allocator.allocate(1);
|
||||||
|
// tee hee
|
||||||
|
::new(&sub_nodes[i]) node(*copy.sub_nodes[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
58
src/main.cpp
58
src/main.cpp
|
@ -109,6 +109,7 @@ class tree
|
||||||
auto top = stack.top();
|
auto top = stack.top();
|
||||||
auto* node = top.second;
|
auto* node = top.second;
|
||||||
auto depth = top.first;
|
auto depth = top.first;
|
||||||
|
stack.pop();
|
||||||
max_depth = std::max(max_depth, depth);
|
max_depth = std::max(max_depth, depth);
|
||||||
for (blt::size_t i = 0; i < node->argc; i++)
|
for (blt::size_t i = 0; i < node->argc; i++)
|
||||||
{
|
{
|
||||||
|
@ -117,7 +118,6 @@ class tree
|
||||||
stack.emplace(depth + 1, node->sub_nodes[i]);
|
stack.emplace(depth + 1, node->sub_nodes[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
stack.pop();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return max_depth;
|
return max_depth;
|
||||||
|
@ -125,9 +125,14 @@ class tree
|
||||||
|
|
||||||
static bool crossover(tree* p1, tree* p2)
|
static bool crossover(tree* p1, tree* p2)
|
||||||
{
|
{
|
||||||
|
if (p1 == nullptr || p2 == nullptr)
|
||||||
|
return false;
|
||||||
auto n1 = p1->select_random_child();
|
auto n1 = p1->select_random_child();
|
||||||
auto n2 = p2->select_random_child();
|
auto n2 = p2->select_random_child();
|
||||||
|
|
||||||
|
if (n1.parent == nullptr || n2.parent == nullptr)
|
||||||
|
return false;
|
||||||
|
|
||||||
const auto& p1_allowed = function_arg_allowed_set_map[to_underlying(n1.parent->type)][n1.index];
|
const auto& p1_allowed = function_arg_allowed_set_map[to_underlying(n1.parent->type)][n1.index];
|
||||||
const auto& p2_allowed = function_arg_allowed_set_map[to_underlying(n2.parent->type)][n2.index];
|
const auto& p2_allowed = function_arg_allowed_set_map[to_underlying(n2.parent->type)][n2.index];
|
||||||
|
|
||||||
|
@ -142,7 +147,7 @@ class tree
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mutate(tree* p)
|
static bool mutate(tree* p)
|
||||||
{
|
{
|
||||||
static std::random_device dev;
|
static std::random_device dev;
|
||||||
static std::mt19937_64 engine{dev()};
|
static std::mt19937_64 engine{dev()};
|
||||||
|
@ -150,11 +155,15 @@ class tree
|
||||||
|
|
||||||
auto n = p->select_random_child();
|
auto n = p->select_random_child();
|
||||||
|
|
||||||
|
if (n.parent == nullptr)
|
||||||
|
return false;
|
||||||
|
|
||||||
auto d = depth(n.child);
|
auto d = depth(n.child);
|
||||||
|
|
||||||
node* new_subtree = node::construct_random_tree(d + 1);
|
node* new_subtree = node::construct_random_tree(d + 1);
|
||||||
n.parent->sub_nodes[n.index] = new_subtree;
|
n.parent->sub_nodes[n.index] = new_subtree;
|
||||||
destroyNode(n.child);
|
destroyNode(n.child);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void evaluate()
|
void evaluate()
|
||||||
|
@ -180,7 +189,8 @@ class tree
|
||||||
|
|
||||||
float fitness()
|
float fitness()
|
||||||
{
|
{
|
||||||
return eval_DNF_SW(root->getImage());
|
auto& img = root->getImage();
|
||||||
|
return eval_DNF_SW(img) * eval_DNF_SW_1(img);
|
||||||
}
|
}
|
||||||
|
|
||||||
void printTree()
|
void printTree()
|
||||||
|
@ -197,6 +207,7 @@ class gp_population
|
||||||
std::unique_ptr<tree> t = nullptr;
|
std::unique_ptr<tree> t = nullptr;
|
||||||
float fitness = 0;
|
float fitness = 0;
|
||||||
};
|
};
|
||||||
|
blt::size_t best = -1;
|
||||||
private:
|
private:
|
||||||
std::array<gp_i, POPULATION_SIZE> pop;
|
std::array<gp_i, POPULATION_SIZE> pop;
|
||||||
public:
|
public:
|
||||||
|
@ -218,17 +229,20 @@ class gp_population
|
||||||
evaluate_population();
|
evaluate_population();
|
||||||
}
|
}
|
||||||
|
|
||||||
tree* select()
|
tree* select(blt::size_t* out = nullptr)
|
||||||
{
|
{
|
||||||
tree* n = nullptr;
|
tree* n = nullptr;
|
||||||
float fitness = 0;
|
float fitness = 0;
|
||||||
for (int i = 0; i < TOURNAMENT_SIZE; i++)
|
for (int i = 0; i < TOURNAMENT_SIZE; i++)
|
||||||
{
|
{
|
||||||
auto& v = pop[choice()];
|
auto index = choice();
|
||||||
|
auto& v = pop[index];
|
||||||
if (n != v.t.get() && v.fitness > fitness)
|
if (n != v.t.get() && v.fitness > fitness)
|
||||||
{
|
{
|
||||||
n = v.t.get();
|
n = v.t.get();
|
||||||
fitness = v.fitness;
|
fitness = v.fitness;
|
||||||
|
if (out != nullptr)
|
||||||
|
*out = index;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return n;
|
return n;
|
||||||
|
@ -240,35 +254,53 @@ class gp_population
|
||||||
static std::mt19937_64 engine{dev()};
|
static std::mt19937_64 engine{dev()};
|
||||||
static std::uniform_real_distribution rand(0.0, 1.0);
|
static std::uniform_real_distribution rand(0.0, 1.0);
|
||||||
|
|
||||||
|
blt::size_t crossover_count = 0;
|
||||||
|
blt::size_t mutation_count = 0;
|
||||||
|
BLT_TRACE("Running Crossover");
|
||||||
for (blt::size_t i = 0; i < POPULATION_SIZE; i++)
|
for (blt::size_t i = 0; i < POPULATION_SIZE; i++)
|
||||||
{
|
{
|
||||||
if (rand(engine) < CROSSOVER_RATE)
|
if (rand(engine) < CROSSOVER_RATE)
|
||||||
{
|
{
|
||||||
auto* p1 = select();
|
blt::size_t i1 = -1, i2 = -1;
|
||||||
auto* p2 = select();
|
auto* p1 = select(&i1);
|
||||||
|
auto* p2 = select(&i2);
|
||||||
|
|
||||||
tree::crossover(p1, p2);
|
// do not crossover the elite
|
||||||
|
if (i1 == best || i2 == best)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (tree::crossover(p1, p2))
|
||||||
|
crossover_count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BLT_TRACE("Running Mutation");
|
||||||
for (blt::size_t i = 0; i < POPULATION_SIZE; i++)
|
for (blt::size_t i = 0; i < POPULATION_SIZE; i++)
|
||||||
{
|
{
|
||||||
if (rand(engine) < MUTATION_RATE)
|
if (rand(engine) < MUTATION_RATE)
|
||||||
{
|
{
|
||||||
auto* p1 = select();
|
blt::size_t i1 = 0;
|
||||||
|
auto* p1 = select(&i1);
|
||||||
|
|
||||||
tree::mutate(p1);
|
if (i1 == best)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(tree::mutate(p1))
|
||||||
|
mutation_count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
BLT_TRACE("ran %d crossovers and %d mutations", crossover_count, mutation_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
void evaluate_population()
|
void evaluate_population()
|
||||||
{
|
{
|
||||||
|
BLT_TRACE("Running Eval");
|
||||||
for (auto& v : pop)
|
for (auto& v : pop)
|
||||||
{
|
{
|
||||||
v.t->evaluate();
|
v.t->evaluate();
|
||||||
v.fitness = v.t->fitness();
|
v.fitness = v.t->fitness();
|
||||||
}
|
}
|
||||||
|
BLT_TRACE("Complete");
|
||||||
}
|
}
|
||||||
|
|
||||||
image& display(blt::size_t i)
|
image& display(blt::size_t i)
|
||||||
|
@ -288,6 +320,7 @@ class gp_population
|
||||||
fitness = pop[j].fitness;
|
fitness = pop[j].fitness;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
best = i;
|
||||||
return {i, fitness};
|
return {i, fitness};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -341,6 +374,7 @@ void update(std::int32_t w, std::int32_t h)
|
||||||
if (ImGui::Button("Regenerate"))
|
if (ImGui::Button("Regenerate"))
|
||||||
{
|
{
|
||||||
BLT_INFO("Regen tree");
|
BLT_INFO("Regen tree");
|
||||||
|
pop = {};
|
||||||
pop.init();
|
pop.init();
|
||||||
best = pop.best_fitness();
|
best = pop.best_fitness();
|
||||||
}
|
}
|
||||||
|
@ -358,10 +392,6 @@ void update(std::int32_t w, std::int32_t h)
|
||||||
{
|
{
|
||||||
BLT_INFO("Uploading");
|
BLT_INFO("Uploading");
|
||||||
texture->upload((void*) pop.display_best().getData().data(), GL_RGB, 0, 0, 0, -1, -1, GL_FLOAT);
|
texture->upload((void*) pop.display_best().getData().data(), GL_RGB, 0, 0, 0, -1, -1, GL_FLOAT);
|
||||||
|
|
||||||
;
|
|
||||||
// if (test_tree->hasTree())
|
|
||||||
// test_tree->printTree();
|
|
||||||
}
|
}
|
||||||
ImGui::Text("Best Fitness: %f", best);
|
ImGui::Text("Best Fitness: %f", best);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue