// Dr. M. Turhan ÇOBAN
// EGE University School of Engineering, Mechanical Engineering Department
// package : Numerical analysis package
// subject : optimization
// group   : Genetic Algorithms gauss random metodu kullanarak.
// Gen Class
// Gen class generates a double number represent a gene

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

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

public static double  gaussrandom(double ixmin,double ixmax,double ix)
{
  double d1=ixmax-ix;
  double d2=ix-ixmin;
  double d=Math.abs(Math.min(d1,d2));
  ix=gaussrandom(ix,d);
  return ix;  
}



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 Gen(double ixmin,double ixmax)
{//randomly generate the gene
 xmin=ixmin;
 xmax=ixmax;
 x=double_random();
}

public Gen(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 Gen()
{
xmin=0;
xmax=1.0;
x=xmin+Math.random();
}

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

public void copyGen(Gen g)
{
xmin=g.xmin;
xmax=g.xmax;
x=g.x;
}

public Gen copyGen()
{
 Gen g=new Gen(this);
 return g;
}

public Gen(Gen Father,Gen Mother)
{setGen(Father,Mother);}
	
public void  setGen(Gen Father,Gen Mother)
{
xmin=Father.xmin;
xmax=Father.xmax;
double xmin1=Mother.xmin;
double xmax1=Mother.xmax;
if(xmin!=xmin1 || xmax!=xmax1) 
{System.err.println("uyumsuz gen boyutu");}
else
{
double r=Math.random();
double d1=xmax-Father.x;
double d2=Father.x-xmin;
double d=Math.abs(Math.min(d1,d2));

double r2=gaussrandom(Father.x,d);
d1=xmax-Mother.x;
d2=Mother.x-xmin;
d=Math.abs(Math.min(d1,d2));
double r3=gaussrandom(Mother.x,d);
x=r2*r+r3*(1-r);
//System.out.println("r2="+r2+"r3="+r3+"r="+r);
if(x<xmin) x=xmin;
else if(x>xmax) x=xmax;
}
}

public void cross1(double crossratio,Gen Father,Gen Mother)
{xmin=Father.xmin;
xmax=Father.xmax;
double xmin1=Mother.xmin;
double xmax1=Mother.xmax;
if(xmin!=xmin1 || xmax!=xmax1) {System.err.println("uyumsuz gen boyutu");}
else 
{
double r1=xmax-xmin; 
double d1=xmax-Father.x;
double d2=Father.x-xmin;
double d=Math.abs(Math.min(d1,d2));
double gr1=gaussrandom(Father.x,d);
d1=xmax-Mother.x;
d2=Mother.x-xmin;
d=Math.abs(Math.min(d1,d2));
double gr2=gaussrandom(Mother.x,d);
x=gr1*crossratio+gr2*(1-crossratio);
if(x<xmin) x=xmin;
else if(x>xmax) x=xmax;
}
}

public void cross2(double crossratio,Gen Father,Gen Mother)
{xmin=Father.xmin;
xmax=Father.xmax;
double xmin1=Mother.xmin;
double xmax1=Mother.xmax;
if(xmin!=xmin1 || xmax!=xmax1) {System.out.println("uyumsuz gen boyutu");}
else
{
double r1=xmax-xmin; 
double d1=xmax-Father.x;
double d2=Father.x-xmin;
double d=Math.abs(Math.min(d1,d2));
double gr1=gaussrandom(Father.x,d);
d1=xmax-Mother.x;
d2=Mother.x-xmin;
d=Math.abs(Math.min(d1,d2));
double gr2=gaussrandom(Mother.x,d);
x=gr1*(1.0-crossratio)+gr2*crossratio;
if(x<xmin) x=xmin;
else if(x>xmax) x=xmax;
}
}

public double getX()
{//return double number equivalent of bit set number   
 return x;  
}
  
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);
  double d1=xmax-x;
  double d2=x-xmin;
  double d=Math.abs(Math.min(d1,d2));
  x=gaussrandom(x,d);  
}
}