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>
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;
for(int i = 0; i < goal.size(); ++i) {
Score error = goal[i] - genome.evaluate_on(i);
for(int i = 0; i < inputs.size(); ++i) {
Score error = outputs[i] - genome.evaluate_on(inputs[i]);
ss += error * error;
}
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::kDiv: 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]";
}
}
@ -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::kDiv: return divi(x, y);
case Gen::kPow: return powi(x, y);
case Gen::kMod: return modi(x, y);
default: return 0;
}
}
@ -103,7 +105,7 @@ using Params = Uniform::param_type;
static Generator generator{0};
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_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::kDiv: 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";
}
}

7
lib/utilities.cpp

@ -18,6 +18,13 @@ int divi(int x, int 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
int powi(int base, int exp){
if(exp < 0) return 0;

10
src/div_test.cpp

@ -23,6 +23,12 @@ static T myDiv(T x, T 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(){
// The bad guys
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&& y : v){
std::cout << x << " / " << y << " = " << std::flush;
std::cout << myDiv(x, y) << std::endl;
std::cout << x << " % " << y << " = " << std::flush;
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
const auto genome_size = 16;
const auto population = 10;
const auto generations = 1000001 / population;
const auto generations = 2000001 / population;
auto evolver = create_evolver(population, genome_size);
evolver.goal = vm["input"].as<std::vector<int>>();
@ -49,9 +49,11 @@ int main(int argc, char** argv){
// SHOW!
auto & best_genome = evolver.current_generation[0].first;
std::cout << "formula:\t" << best_genome.as_formula() << std::endl;
std::cout << "continuation:\t";
for(int i = 0; i < 50; ++i){
std::cout << best_genome.evaluate_on(i) << ", ";
std::cout << "continuation:\n";
static const std::vector<const int> inputs = {2003, 1337, 7877, 5732, 8315, 4466, 0354, 8923, 8888, 0000, 4059, 2403};
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;
}