
/* modified on 3 February 2001 by Peter Hakel */

#include "const.h"
#include "type.h"
#include "extern.h"
#include "exfunc.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

void initdata()
{ /* initialize global parameters */

/*   nin     :   total number of parameters needed by the fitness evaluator
     nvars   :   number of variable parameters (nvars<=nin); these will be encoded into chromosomes
     plistin :   array (size nin) holding values of parameters passed to the fitness evaluator
     plower  :   array (size nvars) of lower limits of ranges of variable parameters
     pupper  :   array (size nvars) of upper limits of ranges of variable parameters
     grid    :   array (size nvars) of grid type flags (char) for chromosome encoding
     lchrom  :   array (size nvars) of chromosome section lengths for encoding of variable parameter values
     nout    :   total number of parameters returned by the fitness evaluator
     plistout:   array (size nout) holding values of parameters passed from the fitness evaluator
     popsize :   population size
     lchron  :   total chromosome length (sum of lchrom's)
     maxgen  :   maximum no. of generations.
     pcross  :   crossover probability
     pmut    :   mutation probability           */

  int i,j;
  FILE *inpfl;

  if( (inpfl = fopen(Ifile,"r")) == NULL){
    printf("error in opening file %s \n",fname);
    exit(1);
  }

  fgets(label,LABEL_LENGTH,inpfl);
  fgets(label,LABEL_LENGTH,inpfl);
  printf(" Enter how many input parameters "); 
  fscanf(inpfl,"%d",&nin);
  printf("\n");
  plistin = malloc(nin*sizeof(double));
  if ( plistin == NULL )
  {
    printf("error in memory allocation for plistin");
    exit(1);
  }

  fgets(label,LABEL_LENGTH,inpfl);
  fgets(label,LABEL_LENGTH,inpfl);
  fgets(label,LABEL_LENGTH,inpfl);
  printf(" Enter how many variables "); 
  fscanf(inpfl,"%d",&nvars);
  printf("\n");
  plower = malloc(nvars*sizeof(double));
  if ( plower == NULL )
  {
    printf("error in memory allocation for plower");
    exit(1);
  }
  pupper = malloc(nvars*sizeof(double));
  if ( pupper == NULL )
  {
    printf("error in memory allocation for pupper");
    exit(1);
  }
  lchrom = malloc(nvars*sizeof(int));
  if ( lchrom == NULL )
  {
    printf("error in memory allocation for lchrom");
    exit(1);
  }
  grid = malloc(nvars*sizeof(char));
  if ( grid == NULL )
  {
    printf("error in memory allocation for grid");
    exit(1);
  }

  fgets(label,LABEL_LENGTH,inpfl);
  fgets(label,LABEL_LENGTH,inpfl);
  fgets(label,LABEL_LENGTH,inpfl);
  lchron = 0;
  for ( i=0; i<nin; i++)
    if ( i<nvars )
    {
      fscanf(inpfl,"%lf",&plower[i]);
      fscanf(inpfl,"%lf",&pupper[i]);
      fscanf(inpfl,"%d",&lchrom[i]);
      lchron += lchrom[i];
      fgets(label,LABEL_LENGTH,inpfl);
      for ( j=0; label[j]==' '; j++ ); /* skip leading blanks in label */
      grid[i] = label[++j]; /* retrieve the second non-blank character: 'i','o', or 't' */
      if ( grid[i]=='o' )
      { /* adjust range of i-th variable for logarithmic encoding and decoding */
        plower[i] = log(plower[i]);
        pupper[i] = log(pupper[i]);
      }
    }
    else
      fscanf(inpfl,"%lf",&plistin[i]);

  if ( nvars<nin ) fgets(label,LABEL_LENGTH,inpfl);
  fgets(label,LABEL_LENGTH,inpfl);
  fgets(label,LABEL_LENGTH,inpfl);
  printf(" Enter how many output parameters "); 
  fscanf(inpfl,"%d",&nout);
  printf("\n");
  plistout = malloc(nout*sizeof(double));
  if ( plistout == NULL )
  {
    printf("error in memory allocation for plistout");
    exit(1);
  }

  fgets(label,LABEL_LENGTH,inpfl);
  fgets(label,LABEL_LENGTH,inpfl);
  fgets(label,LABEL_LENGTH,inpfl);
  printf(" Enter population size - popsize-> "); 
  fscanf(inpfl,"%d",&popsize);
  printf("\n");

  fgets(label,LABEL_LENGTH,inpfl);
  fgets(label,LABEL_LENGTH,inpfl);
  fgets(label,LABEL_LENGTH,inpfl);
  printf(" Enter max. generations - maxgen-> "); 
  fscanf(inpfl,"%d",&maxgen);
  printf("\n");

  fgets(label,LABEL_LENGTH,inpfl);
  fgets(label,LABEL_LENGTH,inpfl);
  fgets(label,LABEL_LENGTH,inpfl);
  printf(" Enter Crossover type xType (lchron - MX) -> "); 
  fscanf(inpfl,"%d",&xType);
  printf("\n");

  fgets(label,LABEL_LENGTH,inpfl);
  fgets(label,LABEL_LENGTH,inpfl);
  fgets(label,LABEL_LENGTH,inpfl);
  printf(" Enter crossover prob - pcross-> "); 
  fscanf(inpfl,"%lf",&pcross);
  printf("\n");

  fgets(label,LABEL_LENGTH,inpfl);
  fgets(label,LABEL_LENGTH,inpfl);
  fgets(label,LABEL_LENGTH,inpfl);
  printf(" Enter mutation prob - pmut-> "); 
  fscanf(inpfl,"%lf",&pmut);
  printf("\n");

  fgets(label,LABEL_LENGTH,inpfl);
  fgets(label,LABEL_LENGTH,inpfl);
  fgets(label,LABEL_LENGTH,inpfl);
  printf(" Enter file name for graph output -fname-> ");
  fscanf(inpfl,"%s",fname);
  printf("Save file is %s\n",fname);
  
  fgets(label,LABEL_LENGTH,inpfl);
  fgets(label,LABEL_LENGTH,inpfl);
  fgets(label,LABEL_LENGTH,inpfl);
  printf(" Enter kind of selection (0/1) -> ");
  fscanf(inpfl,"%d", &selector);
  printf(" Selection is %d\n", selector);

  fgets(label,LABEL_LENGTH,inpfl);
  fgets(label,LABEL_LENGTH,inpfl);
  fgets(label,LABEL_LENGTH,inpfl);
  printf(" Enter mating pool choice (0/1)-> ");
  fscanf(inpfl,"%d", &seller);
  printf(" Mating pool is chosen %d\n", seller);

  fgets(label,LABEL_LENGTH,inpfl);
  fgets(label,LABEL_LENGTH,inpfl);
  fgets(label,LABEL_LENGTH,inpfl);
  printf(" Enter Cmult (1.2 - 2.0)-> ");
  fscanf(inpfl,"%lf", &Cmult);
  printf(" Cmult is %lf\n", Cmult);

  fclose(inpfl);
  printf("\n");
  randomize();
  ncross = 0; nmut = 0;
}

void initpop()
{ /* initialize a random population */

  IPTR pj;
  int j1;
  int j;
  
  op = &opop[0];
  np = &npop[0];
  
  for (j = 0; j < popsize; j++){
    pj = &(opop[j]);
    for (j1 = 0; j1 < lchron; j1++){
      pj->chrom[j1] = flip(0.5); 
    }

    /* pj->fitness = eval(&(pj->chrom[0])); */
    enqueue(&(pj->chrom[0]));
    
    pj->parent1 = pj->parent2 = 0;
  }
/*ORIGINAL
  for (j = 0; j < popsize; j++)
  {
    pj = &(opop[j]);
    pj->fitness = dequeue();
  }
*/
  p_dequeue();
  for (j = 0; j < popsize; j++)
  { 
    pj = &(opop[j]);
    pj->fitness = fitarray[j];
  }
  
}

void initreport()
{
  FILE *fp;

  printf("\n\nPopulation Size (popsize)  %d\n",popsize);
  printf("Chromosome Length (lchron)  %d\n",lchron);
  printf("Maximum num of Generations(maxgen)  %d\n",maxgen);
  printf("Crossover Probability (pcross)  %lf\n",pcross);
  printf("Mutation Probability (pmut)  %lf\n",pmut);
  printf("\n\t\tFirst Generation Stats  \n\n");
  printf("Maximum Fitness  %lf\n",max);
  printf("Average Fitness  %lf\n",avg);
  printf("Minimum Fitness  %lf\n",min);

  if( (fp = fopen(fname,"a")) == NULL){
    printf("error in opening file %s \n",fname);
    exit(1);
  }else{
    raw_stat(fp, op);
    /**fprintf(fp, " %3d %lf %lf %lf \n",gen, max, avg, min);*/
    fclose(fp);
  }
  raw_stat(stdout, op);
}

void initialize()
{ /* initialize everything */
  initdata();
  initqueue(); /* parameter queue "constructor" in eval.c */
  printf("after initfuncs\n");
  initfuncs();
  initpop();
  printf("after initPOP\n");

  statistics(op);
  printf("after STATS\n");
  scalepop(op);

  statistics(op);
  initreport();
}


void initfuncs()
{
  int i;

  for(i = 0; i < NBFUNC; i++) {
    generation[i] = gen0;
    seltor[i] = roulette;
  }
  generation[1] = gen1;
  generation[2] = gen0_scaled;
  generation[3] = gen1_scaled;
  seltor[1] = roulette2;
  seltor[2] = scaled_roulette;
}
