Browse Source

Adds the operator % in genome. Some other stuff.

master
Joshua Moerman 9 years ago
parent
commit
d91027933c
  1. 7
      lib/evolve.cpp
  2. 5
      lib/genome.cpp
  3. 7
      lib/utilities.cpp
  4. 10
      src/div_test.cpp
  5. 10
      src/main.cpp

7
lib/evolve.cpp

@ -7,9 +7,12 @@
#include <iostream> #include <iostream>
static Score score(const std::vector<int>& goal, Genome const & genome){ static Score score(const std::vector<int>& goal, Genome const & genome){
static const std::vector<const int> inputs = {2003, 1337, 7877, 5732, 8315, 4466, 0354, 8923, 8888, 0000, 4059};
static const std::vector<const int> outputs = {2, 4, 3, 4, 3, 0, 2, 2, 0, 0, 1};
Score ss = 0; Score ss = 0;
for(int i = 0; i < goal.size(); ++i) { for(int i = 0; i < inputs.size(); ++i) {
Score error = goal[i] - genome.evaluate_on(i); Score error = outputs[i] - genome.evaluate_on(inputs[i]);
ss += error * error; ss += error * error;
} }
return ss; return ss;

5
lib/genome.cpp

@ -31,6 +31,7 @@ std::ostream & operator<<(std::ostream& out, Gen const & g){
case Gen::kMult: return out << "[* " << g.x << ' ' << g.y << ']'; case Gen::kMult: return out << "[* " << g.x << ' ' << g.y << ']';
case Gen::kDiv: return out << "[/ " << g.x << ' ' << g.y << ']'; case Gen::kDiv: return out << "[/ " << g.x << ' ' << g.y << ']';
case Gen::kPow: return out << "[^ " << g.x << ' ' << g.y << ']'; case Gen::kPow: return out << "[^ " << g.x << ' ' << g.y << ']';
case Gen::kMod: return out << "[% " << g.x << ' ' << g.y << ']';
default: return out << "[error]"; default: return out << "[error]";
} }
} }
@ -75,6 +76,7 @@ static int calc_op(Gen::Type const & op, int const & x, int const & y){
case Gen::kMult: return x * y; case Gen::kMult: return x * y;
case Gen::kDiv: return divi(x, y); case Gen::kDiv: return divi(x, y);
case Gen::kPow: return powi(x, y); case Gen::kPow: return powi(x, y);
case Gen::kMod: return modi(x, y);
default: return 0; default: return 0;
} }
} }
@ -103,7 +105,7 @@ using Params = Uniform::param_type;
static Generator generator{0}; static Generator generator{0};
static Uniform distribution; static Uniform distribution;
static auto random_type = std::bind(distribution, generator, Params(0, Gen::kTypes-1)); static auto random_type = std::bind(distribution, generator, Params(0, Gen::kDiv));
static auto random_const = std::bind(distribution, generator, Params(-20, 20)); static auto random_const = std::bind(distribution, generator, Params(-20, 20));
static auto random_node = [](int n){ return distribution(generator, Params(0, n-1)); }; static auto random_node = [](int n){ return distribution(generator, Params(0, n-1)); };
@ -219,6 +221,7 @@ std::string Genome::as_formula() const{
case Gen::kMult: results[i] = x + "*" + y; break; case Gen::kMult: results[i] = x + "*" + y; break;
case Gen::kDiv: results[i] = x + "/" + y; break; case Gen::kDiv: results[i] = x + "/" + y; break;
case Gen::kPow: results[i] = x + "^" + y; break; case Gen::kPow: results[i] = x + "^" + y; break;
case Gen::kMod: results[i] = x + "%" + y; break;
default: results[i] = "err"; default: results[i] = "err";
} }
} }

7
lib/utilities.cpp

@ -18,6 +18,13 @@ int divi(int x, int y){
return x / y; return x / y;
} }
int modi(int x, int y){
if(!y) return 0;
if(x == numeric_limits<int>::min() && y == -1) return 0;
return x % y;
}
// exponentiation by squaring // exponentiation by squaring
int powi(int base, int exp){ int powi(int base, int exp){
if(exp < 0) return 0; if(exp < 0) return 0;

10
src/div_test.cpp

@ -23,6 +23,12 @@ static T myDiv(T x, T y){
return x / y; return x / y;
} }
static T myMod(T x, T y){
if(!y) return 0;
if(x == numeric_limits<T>::min() && y == -1) return 0;
return x % y;
}
int main(){ int main(){
// The bad guys // The bad guys
vector<T> v = {numeric_limits<T>::min(), -1, 0, 1, numeric_limits<T>::max()}; vector<T> v = {numeric_limits<T>::min(), -1, 0, 1, numeric_limits<T>::max()};
@ -34,8 +40,8 @@ int main(){
for(auto&& x : v){ for(auto&& x : v){
for(auto&& y : v){ for(auto&& y : v){
std::cout << x << " / " << y << " = " << std::flush; std::cout << x << " % " << y << " = " << std::flush;
std::cout << myDiv(x, y) << std::endl; std::cout << myMod(x, y) << std::endl;
} }
} }
} }

10
src/main.cpp

@ -29,7 +29,7 @@ int main(int argc, char** argv){
// TODO: make these program options // TODO: make these program options
const auto genome_size = 16; const auto genome_size = 16;
const auto population = 10; const auto population = 10;
const auto generations = 1000001 / population; const auto generations = 2000001 / population;
auto evolver = create_evolver(population, genome_size); auto evolver = create_evolver(population, genome_size);
evolver.goal = vm["input"].as<std::vector<int>>(); evolver.goal = vm["input"].as<std::vector<int>>();
@ -49,9 +49,11 @@ int main(int argc, char** argv){
// SHOW! // SHOW!
auto & best_genome = evolver.current_generation[0].first; auto & best_genome = evolver.current_generation[0].first;
std::cout << "formula:\t" << best_genome.as_formula() << std::endl; std::cout << "formula:\t" << best_genome.as_formula() << std::endl;
std::cout << "continuation:\t"; std::cout << "continuation:\n";
for(int i = 0; i < 50; ++i){ static const std::vector<const int> inputs = {2003, 1337, 7877, 5732, 8315, 4466, 0354, 8923, 8888, 0000, 4059, 2403};
std::cout << best_genome.evaluate_on(i) << ", "; static const std::vector<const int> outputs = {2, 4, 3, 4, 3, 0, 2, 2, 0, 0, 1, -1};
for(int i = 0; i < inputs.size(); ++i){
std::cout << inputs[i] << " = " << outputs[i] << " = " << best_genome.evaluate_on(i) << ", " << std::endl;
} }
std::cout << std::endl; std::cout << std::endl;
} }