// Dr. M. Turhan ÇOBAN
// EGE University School of Engineering, Mechanical Engineering Department
// package : Numerical analysis package
// subject : optimization
// group   : Genetic Algorithms 
// Gene Class
// Gene class generates digital(binary) array to represent a double number
// actual binary defination changes depends on number of bits, xmin and xmax
// binary data stored in b BitSet array	

import java.util.*;
import java.io.*;

public class G extends Object
{ 
public double xmin,xmax;//maximum and minimum limits of double number
public double x;

public static double  gaussrandom(double xort,double r)
{ //r yayılma bölgesi
   //xort ortalama değer
 int iset=0;
 double gset=0;
 double fac,rsq,v1,v2;
 double aret=0;
 if(iset==0)
 {
   do{
	 v1=2.0*Math.random()-1.0;
	 v2=2.0*Math.random()-1.0;
	 rsq=v1*v1+v2*v2;  
     }while(rsq>=1.0 || rsq==0.0);	   
   fac=Math.sqrt(-2.0*Math.log(rsq)/rsq);
   gset=v1*fac;
   iset=1;
   aret=v2*fac;
 }
 else
 {
 iset=0;
 aret=gset;
 }
 return aret/4.0*r+xort;	
 }
 
public G(double ixmin,double ixmax)
{//randomly generate the gene
 xmin=ixmin;
 xmax=ixmax;
 x=double_random();
}

public G(double s,double ixmin,double ixmax)
{
xmin=ixmin;
xmax=ixmax;
//generate gene equal to a given string
if((s>=xmin)&& (s<=xmax)) x=s;
else if(s<xmin) x=xmin;
else if(s>xmax) x=xmax;
}


public G()
{
xmin=0;
xmax=1.0;
x=xmin+Math.random();
}

public G(G g)
{
xmin=g.xmin;
xmax=g.xmax;
x=g.x;
}

public void copyG(G g)
{
xmin=g.xmin;
xmax=g.xmax;
x=g.x;
}

public G copyGene()
{
 G g=new G(this);
 return g;
}

public G(G Father,G Mother)
{setGene(Father,Mother);}
	
public void  setGene(G Father,G Mother)
{
xmin=Father.xmin;
xmax=Father.xmax;
double r1=xmax-xmin; 
double r=Math.random();
x=gaussrandom(Father.x,r1)*r+gaussrandom(Mother.x,r1)*(1-r);
}

public void cross1(double crossratio,G Father,G Mother)
{xmin=Father.xmin;
xmax=Father.xmax;
double r1=xmax-xmin; 
x=gaussrandom(Father.x,r1)*crossratio+gaussrandom(Mother.x,r1)*(1-crossratio);
}

public void cross2(double crossratio,G Father,G Mother)
{xmin=Father.xmin;
 xmax=Father.xmax;
 double r1=xmax-xmin; 
 x=gaussrandom(Father.x,r1)*(1-crossratio)+gaussrandom(Mother.x,r1)*crossratio;
}
  
public void clear()
{//fill the entire population with zero
x=xmin;}

public void fill()
{//fill the entire population with ones
x=xmax;}


public boolean boolean_random()
{
if(Math.random()<=0.5) return false;
else return true;
}

public double double_random()
{ return (xmin+Math.random()*(xmax-xmin));}

public void mutate()
{ 	
  double r=(xmax-xmin);
  x=gaussrandom(x,r);  
}

}