next up previous contents
Next: Example Implementation for ptrace Up: No Title Previous: Appendix

 

Genetic Algorithm Implementation

A very simple version of a GA for search and optimisation may be implemented as follows:

#include <iostream.h>
#include <stdlib.h>

#define unsigned char UCHAR;
#define unsigned short USHORT;

#define DEFAULT_MUTATION_PROB  0.1
#define DEFAULT_CROSSOVER_PROB 0.5

// CLASS for an individual 

class Individual {
private:
  UCHAR* chr;                 // pointer to the chromosome
  USHORT chr_sz;              // size of the chromosome
  double f;                   // fitness value
  float pm;                   // mutation rate
protected:                    // fitness function pointer
  double (*Fit_Func) (UCHAR*);
public:
  Individual (USHORT size, double (*F)(UCHAR*)); // constructor
  ~Individual (void) {delete [] chr;};           // destructor
  Individual& operator= (Individual& I);         // copy
  UCHAR&      operator[] (unsigned idx) {        // index of chr
                return *(chr+idx);};
  void Init (void);           // initiate individual
  void Mutate (void);         // mutate individual
  void Prn_F  (void) {cout << f << " ";};  // print out fitness
  double Eval (void) {f = Fit_func(chr);}; // determine fitness
  double F    (void) {return f;};
  UCHAR* X    (void) {return char;};
};
// STANDARD CONSTRUCTOR
Indidvidual::Individual (USHORT size, double (*F) (UCHAR*)) {
  : chr_sz(size) {
  Fit_Func = F;               // set up fitness funciton pointer
  chr = new UCHAR [chr_sz];   // create new chromosome
  pm = DEFAULT_MUTATION_PROB;
}
// COPY OPERATOR
Individual& Individual::operator= (Individual& I) {
  if (this != &I) {           // if I is not this I
    delete [] chr;            // delete old I
    chr_sz = I.chr_sz;        // create new one 
    pm = I.pm;                // and copy objects
    Fit_Func = I.Fit_Func;
    chr = new UCHAR [chr_sz];
    for (int i=0; i<chr_sz; i++)
      *(chr+i) = *(I.chr+i);
  }
  return *this;
}
// INITIALIZE INVID
void Individual::Init (void) {
  for (int i=0; i<chr_sz; i++) 
    chr[i] = (UCHAR) rand ();
}
// MUTATION -- because 8 bit are treated together the mutation of
// one bit is a bit more complicated
void Individual::Mutate (void) {
  UCHAR mask;
  for (int i=0; i<chr_sz; i++) {
    mask = 0;
    for (int j=0; j<8; j++) {
      mask <<= 1;
      if (rand () % 1000 < pm * 1000)
        mask += 1;
    }
    chr[i] ^= mask;
  }
}
  
// CLASS FOR A POPULATION

class Population {
private:
  Individual* Pa;         // pointer to parents
  Individual* Ch;         // pointer to children
  USHORT pa_sz;           // number of pa
  USHORT ch_sz;           // number of ch
  USHORT iv_sz;           // size of chromosome
  float pc;               // crossover probab
protected:
  void Cross (UCHAR* p1, UCHAR* p2);
  void Sort  (Individual* p, USHORT sz);
public:
  Population (USHORT p_sz, USHORT c_sz, 
              USHORT i_sz, double (*F) (UCHAR*));
  ~Population (void) {delete [] Pa;};
  void Init   (void);      // init population
  void Prn_F  (void);      // print out fitness
  void Mate   (USHORT no); // mate the population
};
// CONSTRUCTOR
Population::Population ( ... ) {
  : pa_sz(p_sz), ch_sz(c_sz), iv_sz(i_sz) {
  Pa = new Individual [pa_sz+ch_sz] (iv_sz,F); 
  Ch = Pa + pa_sz;
  pc = DEFAULT_CROSSOVER_PROB;
}
// INIT THE POPULATION
void Population::Init (void) {
  for (int i=0; i<pa_sz+ch_sz; i++) 
    Pa[i].Init();
}
// PRINT OUT FITNESS
void Population::Prn_F (void) {
  cout << "Parents:  ";
  for (int i=0; i<pa_sz; i++) 
    Pa[i].Prn_F();
  cout << endl;
  cout << "Children: ";
  for (int i=0; i<ch_sz; i++)
    Ch[i].Prn_F();
  cout << endl;
}
// MATE THE POPULATION AND SELECT THE BEST ONES
void Population::Mate (USHORT no) {
  for (int loop=0; loop<no; loop++) {
    for (int i=0; i<pa_sz; i++) 
      Pa[i].Eval();   // determine parent's fitness
    Sort (Pa, pa_sz); // sort pa corresp to fitness
    for (in i=0; i<ch_sz-1; i+=2) {
      Ch[i]   = P[rand()%pa_sz]; // randomly select
      Ch[i+i] = P[rand()%pa_sz]; // two mates
      Cross (Ch[i].X(), Ch[i+1].X()); // crossover
      Ch[i].Mutate();
      Ch[i+1].Mutate();
    }
    for (int i=0; i<ch_sz; i++)  // evaluate children
      Ch[i].Eval();
    Sort (Pa, pa_sz + ch_sz);    // sort and merge Pa/Ch
  }
}
// CROSSOVER
void Population::Cross (UCHAR* a, UCHAR* b) {
  UCHAR xor_mask, and_mask;
  for (int i=0; i<iv_sz; i++) {
    and_mask = 0;
    for (int j=0; j<8; j++) {
      and_mask <<= 1;
      if (rand () % 1000 < pc * 1000)
        and_mask += 1;
    }
    xor_mask = a[i] ^ b[i];
    xor_mask &= ~and_mask;
    a[i] ^= xor_mask;
    b[i] ^= xor_mask;
  }
}
// SORT
void Population::Sort (Individual* p, USHORT sz) {
  Individual tmp(iv_sz,NULL);
 
  ... any sorting algorithm should do ... 

}


next up previous contents
Next: Example Implementation for ptrace Up: No Title Previous: Appendix

Commander
Thu Oct 22 15:09:09 GMT 1998