This commit is contained in:
2014-10-19 22:30:08 +02:00
parent 0a901c7e4b
commit 0238312a5b
15 changed files with 561 additions and 37 deletions

19
src/Genetics/Except.h Normal file
View File

@@ -0,0 +1,19 @@
#ifndef _GENETICS_EXCEPT_H_
#define _GENETICS_EXCEPT_H_
#include <string>
namespace Shin
{
namespace Genetics
{
class Exception
{
public:
Exception(const std::string &s): str(s) {};
const char* what()const noexcept {return str.c_str();};
protected:
std::string str;
};
}
}
#endif

79
src/Genetics/Generation.h Normal file
View File

@@ -0,0 +1,79 @@
#ifndef _GENETICS_GENERATION_H_
#define _GENETICS_GENERATION_H_
#include <vector>
#include <float.h>
#include <cstddef>
#include "Individual.h"
namespace Shin
{
namespace Genetics
{
template <class _T>
class Generation
{
public:
/* constructors and so */
Generation ():individual() {}
Generation (const Generation &old):individual(old.individual) {}
Generation& operator=(const Generation &g) {individual=g.individual; return *this;}
/* generation manipulation */
size_t size() {return individual.size();}
_T& operator[](const size_t i) { return individual[i];}
void add(const _T &a) { individual.push_back(a);}
inline auto begin() {return individual.begin();};
inline auto end() {return individual.end();};
/* different fitness counting */
double absoluteFitness()
{
return 0.0;
}
double relativeFiness()
{
return 0.0;
}
double bestFitness()
{
double f=DBL_MIN;
for(const _T &a:individual)
if(f < a.getFitness())
f=a.getFitness();
return f;
}
double worstFitness()
{
double f=DBL_MAX;
for(const _T &a:individual)
if(f > a.getFitness())
f=a.getFitness();
return f;
}
double averageFitness()
{
double f=0;
for(const _T &a:individual)
f+=a.getFitness();
return f/individual.size();
}
protected:
std::vector<_T> individual;
};
}
}
#endif

View File

@@ -0,0 +1,94 @@
#ifndef _GENETICS_GENCREATOR_H_
#define _GENETICS_GENCREATOR_H_
#include "Generation.h"
#include "Individual.h"
namespace Shin
{
namespace Genetics
{
template <class _T>
class GenerationCreater
{
public:
Generation<_T> operator()(Generation<_T> &g) {return generate(g);}
virtual Generation<_T> generate(Generation<_T> &gen)=0;
virtual ~GenerationCreater() {}
protected:
unsigned maxGenerationSize=150;
/* static void run(GenerationCreater* r,unsigned long from, unsigned long to,unsigned long fitness, Generation *gen, Generation *s)
{ r->runner(from,to,fitness,gen,s); }
virtual void runner(unsigned long from, unsigned long to,unsigned long fitness, Generation *gen, Generation *s)=0;
*/
};
template <class _T>
class Roulete: public GenerationCreater<_T>
{
public:
Generation<_T> generate(Generation<_T> &gen) override;
protected:
};
}
}
template <class _T>
Shin::Genetics::Generation< _T > Shin::Genetics::Roulete<_T>::generate(Shin::Genetics::Generation< _T >& gen)
{
Generation<_T> newGen;
long fitness=0;
for(const _T &a:gen)
{
fitness+=a.fitness();
}
double avFitness=gen.averageFitness();
for(unsigned int i=0;i<gen.size() && i < this->maxGenerationSize*2/3;i++)
{
if(gen[i].getFitness() >= avFitness)
{
newGen.add(gen[i]);
if(rand()%20==0)
{
newGen.add(gen[i].combine(gen[i]));
newGen[newGen.size()-1].mutate();
}
}
}
if(fitness==0)
fitness++;
while(newGen.size()< this->maxGenerationSize)
{
unsigned int x=rand()%(fitness+1);
unsigned int y=rand()%(fitness+1);
unsigned int xIndividual=0;
unsigned int yIndividual=0;
while( x > 0 && xIndividual < gen.size())
{
x-=gen[xIndividual].fitness();
if(x>0)
++xIndividual;
}
while(y>0 && yIndividual <gen.size())
{
y-=gen[yIndividual].getFitness();
if(y>0)
yIndividual++;
}
xIndividual=xIndividual%(gen.size());
yIndividual=yIndividual%(gen.size());
newGen.add(gen[xIndividual].combine(gen[yIndividual]));
if(rand()%20==0)
newGen[newGen.size()-1].mutate();
}
return newGen;
}
#endif

View File

@@ -2,12 +2,97 @@
using namespace Shin::Genetics;
/*S::XXY S::Genetics::getSolution()
/*
Generation Roulete::generate(Generation& gen)
{
while(1)
Generation s;
long fitness=0;
for (unsigned int i=0;i<gen.size();i++)
fitness+=abs(gen[i]->getFitness());
unsigned int size=150;
double avFitness=(gen.bestFitness()+gen.averageFitness())/2;
for(unsigned int i=0;i<gen.size() && i < size*2/3;i++)
{
if(gen[i]->getFitness() > avFitness)
{
s.add(gen[i]);
if(rand()%20==0)
{
s.add(gen[i]->combine(gen[i]));
s[s.size()-1]->mutate();
}
}
}
size-=s.size();
if(size>gen.size())
size=gen.size();//+(gen.size()+1)/2;
if(fitness==0)
fitness++;
std::vector <std::thread *> threads;
if((size > 1000))
{
long step=size/4;
for(int i=0;i<4;i++)
{
std::cout << "f: "<< (i*step) << ", t: "<< ((i+1)*step) << "\n";
std::thread *a= new std::thread(run,this,i*step,i==3?(size+1):((i+1)*step+1),fitness,&gen,&s);
// a->join();
// delete a;
threads.push_back(a);
}
}else
{
this->runner(0,size+1,fitness,&gen,&s);
// std::thread *a= new std::thread(run,this,0,size+1,fitness,&gen,&s);
// threads.push_back(a);
}
for(std::thread *a:threads)
{
a->join();
delete a;
}
return s;
}
void Roulete::runner(long unsigned int from, long unsigned int to,unsigned long fitness, Generation *gen, Generation *s)
{
for(int i=from;i<to;i++)
{
unsigned int x=rand()%(fitness+1);
unsigned int y=rand()%(fitness+1);
unsigned int xIndividual=0;
unsigned int yIndividual=0;
while( x > 0 && xIndividual < gen->size())
{
x-=gen->operator[](xIndividual)->getFitness();
if(x>0)
++xIndividual;
}
while(y>0 && yIndividual <gen->size())
{
y-=gen->operator[](yIndividual)->getFitness();
if(y>0)
yIndividual++;
}
xIndividual=xIndividual%(gen->size());
yIndividual=yIndividual%(gen->size());
// std::cout << fitness << " - " << xIndividual <<" - " << yIndividual << "\n";
s->add(gen->operator[](xIndividual)->combine(gen->operator[](yIndividual)));
if(rand()%20==0)
s->operator[](s->size()-1)->mutate();
}
}
*/

View File

@@ -1,44 +1,73 @@
#ifndef _GENETICS_H_
#define _GENETICS_H_
#include "Generation.h"
#include "Except.h"
#include "GenerationCreater.h"
#include <vector>
#include <iostream>
#include <thread>
#include <mutex>
namespace Shin
{
namespace Genetics
{
class XXY
{
};
class Entity
/*
class Roulete: public GenerationCreater
{
public:
virtual void mutate()=0;
virtual Entity& combine(const Entity &s)=0;
virtual double getFitness()=0;
private:
};
class Generation
{
public:
double absoluteFitness();
double relativeFiness();
double bestFitness();
double worstFitness();
double averageFitness();
unsigned long size();
Generation generate(Generation &gen) override;
protected:
virtual void runner(unsigned long from, unsigned long to,unsigned long fitness, Generation *gen, Generation *s);
};
template <typename _T>
*/
template <class _T, typename _C=Roulete<_T>>
class Genetics
{
public:
XXY getSolution(_T);
Genetics():c(*new _C()),generation(),deleteCreater(1) {}
Genetics(GenerationCreater<_T> *gc):c(gc),generation() {}
virtual ~Genetics()
{
if(deleteCreater)
delete &c;
}
void addIndividual (const _T &ind) { generation.add(ind); }
_T& getSolution(int maxGenerations,int targetFitness)
{
srand(time(NULL));
for(int round=0;round<maxGenerations;round++)
{
makeRound(round);
std::cout << "Round: " << round << " " << generation.size() << " " << generation.bestFitness() <<" - " << generation.worstFitness() << "\n";
for(_T& t:generation)
{
if(t.getFitness()>=targetFitness)
return t;
}
}
double maxFitness=generation.bestFitness();
for(_T& t:generation)
{
if(t.getFitness()==maxFitness)
return t;
};
throw Exception("Error finding individual with best Fitess");
}
void makeRound(const int round)
{
if(round%500==1)
srand(time(NULL));
generation=c(generation);
}
protected:
GenerationCreater<_T> &c;
Generation<_T> generation;
bool deleteCreater=0;
private:
};

View File

@@ -0,0 +1,3 @@
#include "Individual.h"

18
src/Genetics/Individual.h Normal file
View File

@@ -0,0 +1,18 @@
#ifndef _GENETICS_INDIVIDUAL_H
#define _GENETICS_INDIVIDUAL_H
namespace Shin
{
namespace Genetics
{
class Individual
{
public:
virtual void mutate()=0;
virtual double getFitness() const=0;
inline double fitness() const {return getFitness();}
private:
};
}
}
#endif // INDIVIDUAL_H

View File

@@ -1,4 +1,4 @@
OBJFILES=./Genetics.o
OBJFILES=./Individual.o ./Genetics.o
LIBNAME=Genetics
@@ -8,10 +8,10 @@ all: lib
lib: $(LIBNAME).so $(LIBNAME).a
$(LIBNAME).so: $(OBJFILES)
$(CXX) -shared $(CXXFLAGS) $(OBJFILES) -o $(LIBNAME).so
$(LIBNAME).so: $(OBJFILES) ./Genetics.h ./Generation.h ./GenerationCreater.h
$(CXX) -shared $(CXXFLAGS) $(OBJFILES) -o $(LIBNAME).so -lpthread
$(LIBNAME).a: $(OBJFILES)
$(LIBNAME).a: $(OBJFILES) ./Genetics.h ./Generation.h ./GenerationCreater.h
rm -f $(LIBNAME).a # create new library
ar rcv $(LIBNAME).a $(OBJFILES)
ranlib $(LIBNAME).a