saving progress
This commit is contained in:
41
genetic.cpp
Normal file
41
genetic.cpp
Normal file
@@ -0,0 +1,41 @@
|
||||
#include "genetic.h"
|
||||
#include <queue>
|
||||
#include <vector>
|
||||
|
||||
namespace genetic {
|
||||
|
||||
template <class T> struct CellEntry {
|
||||
float score;
|
||||
T cell;
|
||||
bool stale;
|
||||
};
|
||||
|
||||
template <class T> struct WorkEntry {
|
||||
const std::vector<CellEntry<T>> &cur;
|
||||
std::vector<CellEntry<T>> &next;
|
||||
int cur_i;
|
||||
};
|
||||
|
||||
// Definitions
|
||||
template <class T> Stats<T> run(Strategy<T> strat) {
|
||||
Stats<T> stats;
|
||||
|
||||
std::queue<WorkEntry<T>> fitness_queue;
|
||||
std::vector<CellEntry<T>> 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<CellEntry<T>> &cur_cells = cells_a;
|
||||
std::vector<CellEntry<T>> &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
|
||||
30
genetic.h
Normal file
30
genetic.h
Normal file
@@ -0,0 +1,30 @@
|
||||
#include <vector>
|
||||
|
||||
namespace genetic {
|
||||
|
||||
template <class T> 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 <class T> struct Stats {
|
||||
std::vector<T> best_cell;
|
||||
std::vector<float> average_fitness;
|
||||
};
|
||||
|
||||
template <class T> Stats<T> run(Strategy<T>);
|
||||
|
||||
} // namespace genetic
|
||||
24
main.cpp
24
main.cpp
@@ -1,6 +1,5 @@
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cfloat>
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
@@ -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 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;
|
||||
}
|
||||
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] << " ";
|
||||
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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user