#include "GAClass.cpp"

/* for De Jong function 1 
#define POP_SIZE 160
#define CHROM_LENGTH 30

#define TOTAL_GENERATIONS 400
#define CROSS_PROB 0.66
#define MUTATE_PROB 0.001 
*/

/* for De Jong function 2  
#define POP_SIZE 500
#define CHROM_LENGTH 24

#define TOTAL_GENERATIONS 200
#define CROSS_PROB 0.66  
#define MUTATE_PROB 0.001  
*/

/* for De Jong function 3   */
#define POP_SIZE 400
#define CHROM_LENGTH 50 

#define TOTAL_GENERATIONS 250
#define CROSS_PROB 0.66 
#define MUTATE_PROB 0.01


/* for De Jong function 4 
#define POP_SIZE 600
#define CHROM_LENGTH 240

#define TOTAL_GENERATIONS 800
#define CROSS_PROB 0.66
#define MUTATE_PROB 0.1 
*/


int main(int argc, char **argv)
{
  
  srand(time(0));
  srand48(time(0));

  cout << TOTAL_GENERATIONS<<endl;

  for (int i = 0; i < 30; i++)
  {
    Population *p = new Population(CHROM_LENGTH, POP_SIZE, TOTAL_GENERATIONS);
    
    p->initialize(CROSS_PROB, MUTATE_PROB);

    p->evolution();
    
    delete p;
  }

  return 0;


}





// for De Jong function 1 's fitness evaluation
//   with the use CMAX = 100.0 for adjusment 
//       of the fitness
double eval1(int *vec)
{
  double x,y,z;
  
  x = y = z = 0.0;
  decode1(vec,x,y,z);
  
  return (100.0 - ((x*x)+(y*y)+(z*z)));

}
void decode1( int *vec,double &x,double &y,double &z  )
{
  int i;
  double k;

  x = y = z = 0.0;
   
  for (i = 1; i < 10; i++) {
    k = pow(2, i - 1);
    x += vec[i] * k;
    y += vec[10 + i] * k;
    z += vec[20 + i] * k;

  }
  k = pow(2, 9);
  x -= vec[0] * k; x /= 100.0;
  y -= vec[10] * k; y /= 100.0;
  z -= vec[20] * k; z /= 100.0;

  return;

}


// for De Jong function 2 's fitness evaluation
//   with the use CMAX = 4000.0 for adjusment 
//       of the fitness
double eval2(int *vec)
{
  double x,y, result;
  
  x = y = 0.0;

  decode2(vec,x,y);

  result = 100*((x*x) - y)*((x*x) - y);
  result += ((1-x)*(1-x));

  return( 4000.0 - result);

}
void decode2( int *vec,double &x,double &y )
{
  int i;
  double k;
  
  x = y = 0.0;

  for (i = 1; i < 12; i++) {
    k = pow(2, i - 1);
    x += vec[i] * k;
    y += vec[12 + i] * k;
  }
  k = pow (2, 11);
  x -= vec[0] * k; x /= 1000.0;
  y -= vec[12] * k; y /= 1000.0;

  return;

}


// for De Jong function 3 's fitness evaluation
//   with the use CMAX = 30 for adjusment 
//       of the fitness
double eval3(int *vec)
{
  int i;
  double s;
  double x[5];

  for (i = 0; i < 5; i++)
    x[i] = 0.0;
  s = 0;
  
  decode3(vec,x);
  for (i = 0; i < 5; i++)
    s += x[i];
    
  return (30 - s);

}
void decode3( int *vec,double *x )
{
  int i, j;
  double k;

   for (i = 0; i < 5; i++)
    x[i] = 0.0;

  for (i = 1; i < 10; i++) {
    k = pow(2, i - 1);
    for (j = 0; j < 5; j++)
      x[j] += vec[j * 10 + i] * k;
  }
  k = pow(2, 9);
  for (j = 0; j < 5; j++) {
    x[j] -= vec[j * 10] * k;
    x[j] /= 100.0;
  }

  return;

}


// for De Jong function 4 's fitness evaluation
//   with the use CMAX = 1300.0 for adjusment 
//       of the fitness
double eval4(int *vec)
{
  int i;
  double result, randD, x[30];

  for(i=0;i<30;i++)
    x[i]=0;
  result = 0.0;
  
  decode4(vec,x);
  
  for(i = 0; i < 30; i++){
    randD= drand48();    
    if(rand() % 2)
      randD *= -1;   
    result += (i + 1) * pow(x[i],4) + randD;
  }
  //result += randD;
  return (1300.0 - result );

}
void decode4( int *vec,double *x)
{
  int i, j;
  double k;
    
  for (j = 0; j < 30; j++)
    x[j] = 0;

  for (i = 1; i < 8; i++) {
    k = pow(2, i - 1);
    for (j = 0; j < 30; j++)
      x[j] += vec[j * 8 + i] * k;
  }
  k = pow(2, 7);
  for (j = 0; j < 30; j++) {
    x[j] -= vec[j * 8] * k;
    x[j] /= 100.0;
  }

  return;

}
