Opti.h listing
// Use genetic algorithm to optimize functions
#ifndef _OPTI_
#define _OPTI_
#include <math>
inline int RandInt(int limit) {return rand()%limit;}
inline double UniRand() {return double(rand())/RAND_MAX;}
class Strand;
class GenePool;
class Opti;
class Mini;
class Maxi;
class Strand{
public:
double *gene;
protected:
int length;
double cost;
public:
Strand() : gene(0), length(0) {}
Strand(int len) : length(len) {gene = new double[length];}
Strand(Strand &s0) : length(s0.length){
gene = new double[length];
this->operator=(s0);
}
Strand(double *v, int len) : length(len) {
gene = new double[length];
for(int i=0; i<len; i++) gene[i] = v[i];
}
~Strand() {if(gene) delete gene;}
int Length(){ return length; }
void Length(int len){
if(length>0) delete gene;
length = len;
gene = new double[length];
}
double& Cost() {return cost;}
void Init(double delta){
for(int i=0; i<length; i++) gene[i] = 2.0*delta*(UniRand()-0.5);
}
void Init(double offset, double delta){
for(int i=0; i<length; i++) gene[i] = 2.0*delta*(UniRand()-0.5) + offset;
}
void Init(Strand& s, double delta){
for(int i=0; i<length; i++) gene[i] = s.gene[i] + 2.0*delta*(UniRand()-0.5);
}
void Init(double v[], double delta){
for(int i=0; i<length; i++) gene[i] = v[i] + 2.0*delta*(UniRand()-0.5);
}
void Init(double v0[], double vdel[]){
for(int i=0; i<length; i++)
gene[i] = v0[i] + 2.0*vdel[i]*(UniRand()-0.5);
}
Strand& operator=(Strand& s){
cost = s.cost;
for(int i=0; i<length; i++) gene[i] = s.gene[i];
return *this;
}
double operator()(int index){return gene[index];}
friend class GenePool;
friend class Opti;
friend class Mini;
friend class Maxi;
};
class GenePool{
public:
Strand *strand;
protected:
int population, length;
public:
GenePool() : population(0), strand(0), length(0) {}
GenePool(int pop) : population(pop), length(0){
strand = new Strand[population];
}
GenePool(int pop, int len) : population(pop){
strand = new Strand[population];
Length(len);
}
virtual ~GenePool() {if(strand) delete strand;}
int Length() {return length;}
void Length(int len){
length = len;
if(strand)
for(int i=0; i<population; i++) strand[i].Length(length);
}
int Population() {return population;}
void Population(int pop){
if(strand) delete strand;
population = pop;
strand = new Strand[population];
}
void Init(double delta){
if(strand && length>0)
for(int i=0; i<population; i++) strand[i].Init(delta);
}
void Init(double delta, double offset){
if(strand && length>0)
for(int i=0; i<population; i++) strand[i].Init(delta, offset);
}
void Init(Strand& s, double delta){
if(strand && length>0)
for(int i=0; i<population; i++) strand[i].Init(s, delta);
}
void Init(double v[], double delta){
if(strand && length>0)
for(int i=0; i<population; i++) strand[i].Init(v, delta);
}
void Init(double v0[], double vdel[]){
strand[0].Init(v0, 0.0);
if(strand && length>0){
for(int i=1; i<population; i++) strand[i].Init(v0, vdel);
}
}
};
class Opti : public GenePool{
protected:
int generations;
Strand trial;
double (*f)(double *);
virtual int Better(int) = 0;
virtual int Better(int, int) = 0;
virtual int Best(){
int index, theMin;
for(index=1,theMin=0; index<population; index++)
theMin = Better(index, theMin) ? index : theMin;
return theMin;
}
public:
Opti(int gen, int pop, int len, double (*func)(double *))
: GenePool(pop, len), trial(len), generations(gen) { f = func; }
void Setf(double (*func)(double *)) {f = func;}
virtual Strand& Optimize();
virtual Strand& Optimize(int numgen){generations = numgen; return Optimize();}
};
class Mini : public Opti{
public:
Mini(int gen, int pop, int len, double (*func)(double *))
: Opti(gen, pop, len, func) {}
virtual int Better(int index){
return trial.cost < strand[index].cost;
}
virtual int Better(int ind1, int ind2){
return strand[ind1].cost < strand[ind2].cost;
}
};
class Maxi : public Opti{
public:
Maxi(int gen, int pop, int len, double (*func)(double *))
: Opti(gen, pop, len, func) {}
virtual int Better(int index){
return trial.cost > strand[index].cost;
}
virtual int Better(int ind1, int ind2){
return strand[ind1].cost > strand[ind2].cost;
}
};
double MiniVec(double solution[], const int& gen, const int& pop,
const int& len, double (*func)(double *), double v0[],
const double& delta);
double MiniOff(double solution[], const int& gen, const int& pop,
const int& len, double (*func)(double *), const double& offset,
const double& delta);
extern "C" double minidel_(double solution[], const int& gen, const int& pop,
const int& len, double (*func)(double *), double v0[], double vdel[]);
double MaxiVec(double solution[], const int& gen, const int& pop,
const int& len, double (*func)(double *), double v0[],
const double& delta);
double MaxiDel(double solution[], const int& gen, const int& pop,
const int& len, double (*func)(double *), double v0[], double vdel[]);
#endif
Mike Forster
Last modified: Wed Apr 2 11:54:11 EST 2003