#include "pgapack.h"

double evaluate ( PGAContext *ctx, int p, int pop );
int myMutation(PGAContext *, int, int, double);

/*******************************************************************
*                   user main program                              *
*******************************************************************/
int main( int argc, char **argv )
{
     PGAContext *ctx; 
     int len, *lower, *upper, i, maxiter;
     
     printf("What string length? ");
     scanf("%d", &len);
     printf("How many iterations? ");
     scanf("%d", &maxiter);
     if (!(lower = (int *)malloc(len * sizeof(int))))
     {
	  fprintf(stderr, "No room to allocate lower.\n");
	  exit(1);
     }
     if (!(upper = (int *)malloc(len * sizeof(int))))
     {
	  fprintf(stderr, "No room to allocate upper.\n");
	  exit(1);
     }
     for (i = 0; i < len; i++)
     {
	  lower[i] = 1;
	  upper[i] = len;
     }
     ctx = PGACreate (&argc, argv, PGA_DATATYPE_INTEGER, len, PGA_MAXIMIZE);
     PGASetRandomSeed(ctx, 1);
     PGASetUserFunction(ctx, PGA_USERFUNCTION_MUTATION, (void *)myMutation);
     PGASetIntegerInitLU(ctx, lower, upper);
     PGASetMaxIter(ctx, maxiter);
     PGASetUp                (ctx);
     PGARun                  (ctx, evaluate);
     PGADestroy              (ctx);
     free(lower);
     free(upper);
     return(0);
}

double evaluate(PGAContext *ctx, int p, int pop)
{
     int stringlen, i, sum = 0;

     stringlen = PGAGetStringLen(ctx);
     for (i = 0; i < stringlen; i++)
	  sum += PGAGetIntegerAllele(ctx, p, pop, i);

     return ((double)sum);
}

int myMutation(PGAContext *ctx, int p, int pop, double mr)
{
     int stringlen, i, k, count = 0;

     stringlen = PGAGetStringLen(ctx);
     for (i = 0; i < stringlen; i++)
	  if (PGARandomFlip(ctx, mr))
	  {
	       k = PGARandomInterval(ctx, 1, stringlen);
	       PGASetIntegerAllele(ctx, p, pop, i, k);
	       count++;
	  }

     return ((double) count);
}
	       
