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

class satici_genetik2
{
public satici_gen G[];    // string of variables makes a genotype1
public boolean Breeder;   //
public int    POPSIZE;           // population size
int    MAXGENS;           // maximum number of generations;
double PMUTATION;         // proportion of mutated variables
double PXOVER;            // probability of crossover;
int    Generation;        // Current generation number
int    NBreeder;   //   Number of survivors in a generation
int    Best; //The best genotype1 in the population
double toplameniyi=0;
double nesileniyi=0;
double xi[],yi[]; //şehir adresleri
      
  public satici_genetik2(String name,int POPSİZEi,int MAXGENSi,double PXOVERi,double PMUTATIONi )
  {double a[][]=Text.readDoubleT(name);  
   double xi[]=a[0];
   double yi[]=a[1];
   int best;
   POPSIZE=POPSİZEi;
   PXOVER=PXOVERi;
   MAXGENS=MAXGENSi;
   PMUTATION=PMUTATIONi;
   G=new satici_gen[POPSIZE+1];
   double totalfitness=0;
   for(int i=0;i<(POPSIZE+1);i++)
   {G[i]=new satici_gen(xi,yi);G[i].setFitness();totalfitness+=G[i].getFitness();}
   double xR,xC=0;
   for(int i=0;i<(POPSIZE+1);i++)
   {xR=G[i].getRFitness()/totalfitness;xC+=xR;G[i].setRFitness(xR);G[i].setCFitness(xC);}
  }
  	
  public void setPopulation()
  {
   double totalfitness=0;
   for(int i=0;i<POPSIZE;i++)
   {G[i]=new satici_gen(xi,yi);}
    evaluate();
  }	
  
  public void evaluate()
  {
   nesileniyi=0;
   double totalfitness=0;
   for(int i=0;i<POPSIZE+1;i++)
   {G[i].setFitness();
    double mesafe=1.0/G[i].getFitness();
    if(mesafe>nesileniyi) nesileniyi=mesafe;
    if(mesafe>toplameniyi) toplameniyi=mesafe;
    totalfitness+=G[i].getFitness();
   }
   double xR=0,xC=0,xRP=G[POPSIZE].getFitness()/totalfitness;
   for(int i=0;i<POPSIZE;i++)
   {xR=G[i].getFitness()/totalfitness;xC+=xR;G[i].setRFitness(xR);G[i].setCFitness(xC);    
    	 if(xR > xRP)
	     {
		 Best=i;
		 G[POPSIZE]=new satici_gen(G[i]); 
		 xRP=G[POPSIZE].getFitness()/totalfitness;  
         }
  }
  }
  
  public satici_gen[] copyPopulation()
  {
	satici_gen Po[]=new satici_gen[POPSIZE+1]; 	
	for(int i=0;i<(POPSIZE+1);i++)
	  { Po[i]=new satici_gen(G[i]);
	    Po[i].Fitness=G[i].Fitness;
	  	Po[i].RFitness=G[i].RFitness;	    
	    Po[i].CFitness=G[i].CFitness;	
	  }
	return Po;  
 }

  	public void select()
	{
	double r,r1,r2,gf0,gf1;
	evaluate();
	//anne baba aday adaylarını seç
	satici_gen Po[]=new satici_gen[POPSIZE+1];
	NBreeder=0;	
	int i,j;
	for(i=0;i<(POPSIZE+1);i++)
    {   r=Math.random();
        gf0=0;
        for(j=0;j<POPSIZE;j++)
        {
        gf1=G[j].getCFitness();
        if((r>=gf0) && (r<=gf1)) 
        {Po[NBreeder]=new satici_gen(G[j]);
        //System.out.println("j= "+j+"gf0="+gf0+"gf1="+gf1+"r="+r+"NBreeder="+NBreeder);
        NBreeder++;break;}
        gf0=gf1; 
        }                    
    }
    // seçilen anne, baba aday adaylarının yeni çocuk yapmalarına olanak ver
      int breed=(int)(POPSIZE*PXOVER);
      int breed3=3*breed;
      satici_gen P1[]=new satici_gen[breed3];
      for(i=0;i<breed3;i++)
	  {  	  
		  int a=(int)(Math.random()*NBreeder);
           int b=(int)(Math.random()*NBreeder); 
           P1[i]=new satici_gen(Po[a],Po[b]);
           //System.out.println("a="+a+"b="+b+"cocuk="+G[i].toString());
           r2=Math.random();	
           //mutasyon olasılığı : PMUTATION  
	       if(r2 < PMUTATION) P1[i].mutate();
	       //System.out.println(NBreeder+" "+G[POPSIZE].mesafe()); 		 
	  }
     //yeni nesilden en başarılılarını seç (Lamark seçimi)
     for(i=0;i<breed;i++)
	 { P1[i].setFitness();
	   P1[i+breed].setFitness();
	   P1[i+2*breed].setFitness();
	   double biggest=1.0e40;
       double mesafe1=1.0/P1[i].getFitness();
       double mesafe2=1.0/P1[i+breed].getFitness();
	   double mesafe3=1.0/P1[i+2*breed].getFitness();
       if(mesafe1<biggest) biggest=mesafe1;
       if(mesafe2<biggest) biggest=mesafe2;
       if(mesafe3<biggest) biggest=mesafe3;
       if(biggest==mesafe1) G[i]=new satici_gen(P1[i]);
       else if(biggest==mesafe2) G[i]=new satici_gen(P1[i+breed]);
       else if(biggest==mesafe3) G[i]=new satici_gen(P1[i+2*breed]);	 
	 } 	  
	  //listenin gerisini seçilen anne baba adaylarıyla doldur
	      for(i=breed;i<POPSIZE;i++)
	      {  int a=(int)(Math.random()*NBreeder);
             G[i]=new satici_gen(Po[a]);   
	      }
    }
    
    public void nesiller()
    {
	for(int i=0;i<MAXGENS;i++) {select();}   
	}
	
    public satici_gen secilmis_nesil()
    {
    nesiller();
    G[POPSIZE].plot();
    return G[POPSIZE];
	}
	
	
  public static void main(String arg[])
  {
    satici_genetik2 sg=new satici_genetik2("sehirler.txt",1000,1000,1.0,0.05 );
    System.out.println("seçilmiş nesil : "+sg.secilmis_nesil().toString());
  }

}  
