package gannuOP.algorithms.differential_evolution;
import gannuOP.algorithms.Optimizer;
import gannuOP.testing.Function;
import gannuOP.testing.Report;
import java.util.ArrayList;
import java.util.Random;
public class SaDE extends Optimizer {
Random g=new Random();
double N(double mean, double std)
{
return g.nextGaussian()*std+mean;
}
@Override
public ArrayList<Report> solve(String parameters, Function fx,
double maxFes, double reportFes, double precision) throws Exception {
int P=0;
int LP=0;
double error;
int best;
ArrayList<Report>reports=new ArrayList<Report>((int)Math.ceil(maxFes/reportFes));
//Loading parameters
String split[]=parameters.split(",");
for(String parameter:split)
{
if(parameter.startsWith("P="))
{
P=Integer.parseInt(parameter.replace("P=", ""));
}
if(parameter.startsWith("LP="))
{
LP=Integer.parseInt(parameter.replace("LP=", ""));
}
}
double CRm=0.5;
double F=0.0;
double CR=0.0;
double ns[][]=new double[4][LP];
double nf[][]=new double[4][LP];
int current=0;
double pk[]={0.25,0.25,0.25,0.25};
//Initialization of population
ArrayList<double []> pop=new ArrayList<double []>(P);
ArrayList<double []> U=new ArrayList<double []>(P);
for(int i=0;i<P;i++)
{
double []X=new double[fx.getD()+1];
for(int j=0;j<fx.getD();j++)
{
X[j]=Optimizer.rndreal(fx.getLimit()[0][j], fx.getLimit()[1][j]);
}
X[fx.getD()]=fx.evaluate(X,precision);
pop.add(X);
double []y=new double[fx.getD()+1];
U.add(y);
}
best=Optimizer.getBestIndividual(pop);
error=pop.get(best)[fx.getD()];
double r=0.0d;
double fes;
int g;
for(fes=(double)P, g=0;fes<maxFes&&error>=precision;fes+=(double)P,g++)
{
int i=0;
for(double []X:pop)
{
int approach=0;
while(true)
{
if(pk[approach]>Optimizer.rndreal(0.0, 1.0))
break;
if(approach<3)
approach++;
else
approach=0;
}
F=N(0.5,0.3);
//HERE TODO CRM median
int r1,r2,r3;
r1=Optimizer.rnd(0, P-1);
r2=r1;
while(r2==r1)
{
r2=Optimizer.rnd(0, P-1);
}
r3=r1;
while(r3==r1||r3==r2)
{
r3=Optimizer.rnd(0, P-1);
}
int jrand=Optimizer.rnd(0, fx.getD()-1);
double []u=U.get(i);
for(int j=0;j<fx.getD();j++)
{
if(Math.random()<CR||j==jrand)
{
u[j]=pop.get(r3)[j]+F*(pop.get(r1)[j]-pop.get(r2)[j]);
}
else
{
u[j]=X[j];
}
}
i++;
u[fx.getD()]=fx.evaluate(u,precision);
}
for(i=0;i<P;i++)
{
double x[]=pop.get(i);
double []u=U.get(i);
if(u[fx.getD()]<x[fx.getD()])
for(int j=0;j<=fx.getD();j++)
x[j]=u[j];
}
best=Optimizer.getBestIndividual(pop);
error=pop.get(best)[fx.getD()];
r+=(double)P;
if(r>=reportFes)
{
r=0.0d;
reports.add(new Report(pop, best, fes));
}
}
reports.add(new Report(pop, best, fes));
return reports;
}
}