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