// Dr. M. Turhan ÇOBAN
// EGE University School of Engineering, Mechanical Engineering Department
// package : Numerical analysis package
// subject : optimization
// group   : Genetic Algorithms 
// Gene13 Class
// Gene3 class generates integer 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 Gene3 extends Object
{
//long imin=0;
int N=18;
public long imax=999999999999999999L;
public long ix;        
public double x;//Limit value for integer(2^N-1)
public double xmin,xmax;//maximum and minimum limits of double number

public Gene3(double ixmin,double ixmax)
{//randomly generate the gene
 xmin=ixmin;
 xmax=ixmax;
 ix=(long)(imax*Math.random());
 x=xmin+(xmax-xmin)*(double)ix/(double)imax;
}


public Gene3(long ixi,double ixmin,double ixmax)
{//randomly generate the gene
 xmin=ixmin;
 xmax=ixmax;
 ix=ixi;
 x=xmin+(double)ix*(xmax-xmin)/(double)imax;
}

public Gene3(Gene3 g)
{
// copy a Gene from another one	
copyGene(g);
}

public void copyGene(Gene3 g)
{
 ix=g.ix;
 x=g.x;
 xmin=g.xmin;
 xmax=g.xmax;
}

public Gene3 copyGene()
{Gene3 g=new Gene3(x,xmin,xmax);
 return g;
}

public Gene3(Gene3 Father,Gene3 Mother)
{cross(Math.random(),Father,Mother);}

public Gene3(double xi,double maxi,double mini)
{setGene(xi,maxi,mini);}


public Gene3(double crossratio,Gene3 Father,Gene3 Mother)
{   if(boolean_random()) cross(crossratio,Father,Mother);
    else                 cross(crossratio,Mother,Father);
} 

public void  setGene(long iix,double ixmin,double ixmax)
{
 xmin=ixmin;
 xmax=ixmax;
 ix=iix;
 x=xmin+(xmax-xmin)*(double)ix/(double)imax;
}

public void  setGene(double idx,double ixmin,double ixmax)
{
 xmin=ixmin;
 xmax=ixmax;
 if(idx>=xmin && idx<=xmax)	x=idx;
 else if(idx<xmin) x=xmin;
 else x=xmax;
 ix=(long)((x-xmin)/(xmax-xmin)*imax+0.99);
}

public void  setGene(double idx)
{

 if(idx>=xmin && idx<=xmax)	x=idx;
 else if(idx<xmin) x=xmin;
 else x=xmax;
 ix=(long)((x-xmin)/(xmax-xmin)*imax);
}	

public void cross(Gene3 Father,Gene3 Mother)
{double crossratio=Math.random();
cross(crossratio,Father,Mother);
}

public double getX()
{return x;}

public void cross(double crossratio,Gene3 Father,Gene3 Mother)
{
Long IntFx=new Long(Father.ix);
String SFx=IntFx.toString();
int nSFx=SFx.length();
Long IntMx=new Long(Mother.ix);
String SMx=IntMx.toString();
int nSMx=SMx.length();
if(nSFx<N)
{String ss="";for(int i=0;i<(N-nSFx);i++){ss+="0";};SFx=ss+SFx;}
if(nSMx<N)
{String ss="";for(int i=0;i<(N-nSMx);i++){ss+="0";};SMx=ss+SMx;}
int N2 = (int)(crossratio*N+0.02)/2;
int N1=2*N2;
int N3=N1+(N-N1)/2;
StringBuffer dest = new StringBuffer(N);
int i; 
for (i = 0; i <N2; i++) 
{ dest.append(SFx.charAt(i));
  dest.append(SMx.charAt(i));
}
for (i = N1; i <N3; i++) 
{ dest.append(SFx.charAt(i));}
for (i = N3; i <N; i++) 
{ dest.append(SMx.charAt(i));}
String s=dest.toString();
long iix=Long.parseLong(s);
ix=iix;
xmin=Father.xmin;
xmax=Father.xmax;
x=xmin+(xmax-xmin)*(double)ix/(double)imax;
}


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

public void mutate()
{
int N1 = (int)(N*Math.random()); 
Long IntFx=new Long(ix);
String SFx=IntFx.toString();
int nSFx=SFx.length();
if(nSFx<N)
{String ss="";for(int i=0;i<(N-nSFx);i++){ss+="0";};SFx=ss+SFx;}
StringBuffer dest = new StringBuffer(N);
int i; 
for (i = 0; i <N; i++) 
{  if(i==N1) 
    {  int i1=(int)(9.0*Math.random());
       String s2=Integer.toString(i1);
       dest.append(s2.charAt(0));
    } 
   else {dest.append(SFx.charAt(i));}
}
String s=dest.toString();
long iix=Long.parseLong(s);
ix=iix;
x=xmin+(xmax-xmin)*(double)ix/(double)imax;	
//==================	
}

public String toString()
{String s;
 s="x="+x+"ix="+ix+"xmin="+xmin+"xmax="+xmax;
 return s;
}
}
