import java.io.*;
import java.text.*;
import java.util.Locale;

abstract class f_xj
{
  // single function  multi independent variable
  // a single value is returned indiced to equation_ref
  // example f[0]=x[0]+sin(x[1])
  //         f[1]=x[0]*x[0]-x[1]
  // func(x,1) returns the value of f[1]
  // func(x,0) returns the value of f[0]

  abstract double func(double x[]);
}

class genotype
{
// each genotype is member of the population
// Genotype is like a chromosone in real life genetic systems
// it can be thought as an evaluation point of a function with n variable
// f(xi)=f(x1,x2,x3,..,x_nvars)
public Gene G[]      ;  // string of variables makes a genotype
public double Fitness;  // genotype's fitness f(xi)
public double Upper[];  // gene's upper bound; xi_lower < xi < xi_upper
public double Lower[];  // Gene's lower bound; xi_lower < xi < xi_upper
public double RFitness; // the relative fitness
public double CFitness; // cumulative fitness
public int NVARS;       // Number of variables(Genes)
public int N;           // Number of bits defining each gene
public boolean Breeder;
  
  public genotype(int iNVARS,double low[],double high[],int iN,f_xj fi)
  {setgenotype(iNVARS,low,high,iN,fi);}
  
  public void setgenotype(int iNVARS,double low[],double high[],int iN,f_xj fi)
  {
  setN(iN);  
  setNVARS(iNVARS);	  
  G=new Gene[NVARS];
  Upper=new double[NVARS];
  Lower=new double[NVARS];
  setLower(low);
  setUpper(high);
  setGene(); 
  setFitness(fi);
  }
  
  public genotype(genotype gi,f_xj fi)
  {setgenotype(gi,fi);}
   
  public void setgenotype(genotype gi,f_xj fi)
  {
  setN(gi.N);  
  setNVARS(gi.NVARS);	  
  G=new Gene[NVARS];
  Upper=new double[NVARS];
  Lower=new double[NVARS];
  setLower(gi.Upper);
  setUpper(gi.Lower);
  for(int i=0;i<NVARS;i++)
    G[i]=gi.G[i].copyGene(); 
  setFitness(fi);
  }
  
  public genotype copygenotype(f_xj fi)
  {
  genotype g1=new genotype(this,fi);
  return g1;
  }
  
  public void setN(int iN)    {N=iN;}
  public void setNVARS(int iNVARS)    {NVARS=iNVARS;}
  public void setLower(double lbound[]) {for(int i=0;i<NVARS;i++) Lower[i]=lbound[i];}
  public void setUpper(double ubound[]) {for(int i=0;i<NVARS;i++) Upper[i]=ubound[i];}
  public void setFitness(f_xj fi) 
  {	 Fitness=fi.func(getGene());}
  public void setRFitness(double isum)  {RFitness=Fitness/isum;}
  public void setCFitness(double ix)  {CFitness=ix;}
  public double getLower(int j) {return Lower[j];}
  public double getUpper(int j) {return Upper[j];}
  public double getFitness() {return Fitness;}
  public double getRFitness(){return RFitness;}
  public double getCFitness(){return CFitness;}
  public void breed() {Breeder=true;}
  public void not_breed() {Breeder=false;}
  public boolean isBreed() {return Breeder;}  
  
    
  public void setGene(int val)
  {  G[val]=new Gene(Lower[val],Upper[val],N);}
  
  public void setGene()
  {  for(int j=0;j<NVARS;j++)	  
	     setGene(j);
  }
  
  public double getGene(int val)
  { return G[val].getX();}  
  
  public double[] getGene()
  {   double x[]=new double[NVARS];
	  for(int j=0;j<NVARS;j++)	  
	     x[j]=getGene(j);
	  return x;     
  }

  public String toString()
  {
  //x values, Fitness,relative fitness and cumulative fitness	  
  String s="";
  for(int j=0;j<NVARS;j++)	  
	 s+=G[j].toString()+" F:";
  s+=getFitness();
  s+="RF:"+getRFitness();
  s+="CF:"+getCFitness();	      	  
  return s;
  }
}  //end of class genotype