diff --git a/genetic.cpp b/genetic.cpp new file mode 100644 index 0000000..1cb7941 --- /dev/null +++ b/genetic.cpp @@ -0,0 +1,41 @@ +#include "genetic.h" +#include +#include + +namespace genetic { + +template struct CellEntry { + float score; + T cell; + bool stale; +}; + +template struct WorkEntry { + const std::vector> &cur; + std::vector> &next; + int cur_i; +}; + +// Definitions +template Stats run(Strategy strat) { + Stats stats; + + std::queue> fitness_queue; + std::vector> cells_a, cells_b; + for (int i = 0; i < strat.num_cells; i++) { + T cell = strat.make_default_cell(); + cells_a.push_back({0, cell, true}); + cells_b.push_back({0, cell, true}); + } + + std::vector> &cur_cells = cells_a; + std::vector> &next_cells = cells_b; + + for (int i = 0; i < strat.num_generations; i++) { + + cur_cells = cur_cells == cells_a ? cells_b : cells_a; + next_cells = cur_cells == cells_a ? cells_b : cells_a; + } +} + +} // namespace genetic diff --git a/genetic.h b/genetic.h new file mode 100644 index 0000000..44e1752 --- /dev/null +++ b/genetic.h @@ -0,0 +1,30 @@ +#include + +namespace genetic { + +template struct Strategy { + // The recommended number of threads is <= number of cores on your pc. + // Set this to -1 use the default value (number of cores - 1) + int num_threads; // Number of worker threads that will be evaluating cell fitness + int num_cells; // Size of the population pool + int num_generations; // Number of times (epochs) to run the algorithm + bool test_all; // Sets whether or not every cell is tested every generation + float test_chance; // Chance to test any given cell's fitness. Relevant only if test_all is false. + + // User defined functions + T (*make_default_cell)(); + float (*fitness)(const T &cell); + void (*mutate)(const T &cell, T *out); + void (*crossover)(const T &a, const T &b, T *out); + + float mutation_chance_per_gen; +}; + +template struct Stats { + std::vector best_cell; + std::vector average_fitness; +}; + +template Stats run(Strategy); + +} // namespace genetic diff --git a/main.cpp b/main.cpp index e13bb39..e60847d 100644 --- a/main.cpp +++ b/main.cpp @@ -1,6 +1,5 @@ #include #include -#include #include #include #include @@ -30,7 +29,7 @@ struct Cell { Cell make_cell(int num_params) { Cell res = {num_params, (float *)malloc(num_params * sizeof(float))}; for (int i = 0; i < num_params; i++) { - res.params[i] = norm_rand() * 100.0f; + res.params[i] = 0; } return res; } @@ -73,18 +72,18 @@ bool operator<(const Cell &a, const Cell &b) { void combine_cells(const Cell &a, const Cell &b, Cell *child) { bool a_first = norm_rand() > 0.5f; for (int i = 0; i < a.n; i++) { - float offset = norm_rand(); - float roll = norm_rand(); + float offset = norm_rand() * 10; + float roll = norm_rand(); if (a_first) { - child->params[i] = (i < a.n / 2 ? a.params[i] : b.params[i]) + (roll > 0.5 ? offset : -offset); + child->params[i] = (i < a.n / 2 ? a.params[i] : b.params[i]) + + (roll > 0.5 ? offset : -offset); } else { - child->params[i] = (i < a.n / 2 ? b.params[i] : a.params[i]) + (roll > 0.5 ? offset : -offset); + child->params[i] = (i < a.n / 2 ? b.params[i] : a.params[i]) + + (roll > 0.5 ? offset : -offset); } } - if (norm_rand() < MUTATION_CHANCE) { - float r = norm_rand(); - child->params[(int)r * (a.n-1)] = r * FLT_MAX; - } + float r = norm_rand(); + child->params[(int)r * (a.n - 1)] = r * 100.0; } int main(int argc, char **argv) { @@ -116,12 +115,19 @@ int main(int argc, char **argv) { combine_cells(cells[j], cells[j + 1], &cells[num_cells / 2 + j]); } if (i % 1000 == 0) { - std::cout << i << "\t" << get_cell_err(cells[0])+get_cell_err(cells[1])+get_cell_err(cells[2]) << std::endl; + std::cout << i << "\t" << get_cell_err(cells[0]) << std::endl; } } std::cout << "Final Answer: "; + float sum = 0; + float product = 1; for (int i = 0; i < cells[0].n; i++) { - std::cout << cells[0].params[i] << " "; + std::cout << cells[0].params[i] << " "; + sum += cells[0].params[i]; + product *= cells[0].params[i]; } std::cout << std::endl; + + std::cout << "Sum: " << sum << std::endl; + std::cout << "Product: " << product << std::endl; } diff --git a/test.txt b/test.txt index b745300..fa05939 100644 --- a/test.txt +++ b/test.txt @@ -1,4 +1,3 @@ -10 1000 100000 3 -0 200 -2 50.0 4 -2 10.0 3 +10 2000 150000 2 +1 200 +0 10000