Lab 6 - Genetic Algorithm Toolkit

This lab is worth 10 points.
Due: Friday February 29, 2008 at 5pm

The multi-objective genetic algorithm toolkit NSGA-II from Kanpur Genetic Algorithms Laboratory will be the basis of this lab. The code has been placed in the /ai/ga/ directory on Helios. Copy the file /ai/ga/nsga2-gnuplot-v1.1.tar to your own directory and unpack the code using the command tar -xf nsga2-gnuplot-v1.1.tar (the unpacked code is also visible in /ai/ga/nsga2-gnuplot-v1.1).

We will be using this toolkit to implement the genetic algorithm example in the book from pages 227 to 229. To implement the code, you need to define the fitness function in the file problemdef.c. Edit the file problemdef.c and comment out the line

# define ctp8
so that it will not run that default fitness function. NSGA-II by default seeks to minimize the fitness function. Since the book example wants to maximize the result of the function, we will need to negate the results (multiply by -1) to get the correct behavior. Fill in the indicated blanks in this code to implement the fitness function for the book's problem:
#define myprob

#ifdef myprob
void test_problem (double *xreal, double *xbin, int **gene, double *obj, double *constr)
{
  double mod, term1, term2, res;
  double st1, st2, ct1, ct2, v1, v2, e1, e2;
  int i;
  char gstr[17];

  mod = 6.0 / (256.0 - 1.0);

  /**************************************************/
  /* Decode bits of gene[0] as term1 and term2 here */
  /**************************************************/

  /* Convert the decoded terms into the range of -3 to 3 */
  term1 = (term1 * mod) - 3.0;
  term2 = (term2 * mod) - 3.0;

  /* Compute the squares of the terms */
  st1 = pow(term1, 2);
  st2 = pow(term2, 2);

  /* Compute the cubes of the terms */
  ct1 = pow(term1, 3);
  ct2 = pow(term2, 3);

  /* Compute (1-x)^2 and (y+1)^2 */
  v1 = pow((1-term1), 2);
  v2 = pow((term2+1), 2);

  /* Compute the two exponential terms */
  e1 = exp((-1 * st1) - v2);
  e2 = exp((-1 * st1) - st2);

  /* Calculate the result of the function */
  res = (v1 * e1) - ((term1 - ct1 - ct2) * e2);

  /* Put the chromosome into a printable string, highest bit to lowest bit */
  for(i = 0; i < 16; i++) {
    gstr[i] = (gene[0][(15-i)] ? '1' : '0');
  }
  gstr[i] = '\0';

  printf("\nvalues: gene=%s x=%f y=%f f(x,y)=%f", gstr, term1, term2, res);
  obj[0] = -1 * res;
}
#endif
Compile the code with the command make. Test your code by running the command nsga2r <rand_seed>. You can use any value from 0 to 1 for the random seed. This will start an interactive dialog. Answer the questions as follows:
 Enter the problem relevant and algorithm relevant parameters ... 
 Enter the population size (a multiple of 4) : 8

 Enter the number of generations : 5

 Enter the number of objectives : 1

 Enter the number of constraints : 0

 Enter the number of real variables : 0

 Enter the number of binary variables : 1

 Enter the number of bits for binary variable 1 : 16

 Enter the lower limit of binary variable 1 : 0

 Enter the upper limit of binary variable 1 : 65536

 Enter the probability of crossover of binary variable (0.6-1.0): 0.7

 Enter the probability of mutation of binary variables (1/nbits): 0.001 

 Do you want to use gnuplot to display the results realtime (0 for NO) (1 for yes) : 0 
Play around with the population size and number of generations to see how they affect the results. Also try changing the mutation and crossover rates to see how those affect the results

Lab Writeup

Attach your modified problemdef.c code to the email. List what values of population size, maximum generations, crossover rate and mutation rate you tested and the best results those combinations produced. How did your results vary when you had a higher number of generations than the default? How did your results differ when you had a higher mutation rate than the default? What other differences did you note in the results when changing these values?