package gannuOP.algorithms.differential_evolution;
import gannuOP.algorithms.Optimizer;
import gannuOP.testing.Function;
import gannuOP.testing.Report;
import java.util.ArrayList;
public class Rand1Bin extends Optimizer {
@Override
public ArrayList<Report> solve(String parameters, Function fx,
double maxFes, double reportFes, double precision) throws Exception {
int P=0;
double error;
int best;
double CR=0.0,F=0.0;
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("F="))
{
F=Double.parseDouble(parameter.replace("F=", ""));
}
if(parameter.startsWith("CR="))
{
CR=Double.parseDouble(parameter.replace("CR=", ""));
}
}
//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.0;
double fes;
for(fes=(double)P;fes<maxFes&&error>=precision;fes+=(double)P)
{
int i=0;
for(double []X:pop)
{
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]);
if(!fx.isValid(u[j], j))
u[j]=X[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];
}
if(error>pop.get(Optimizer.getBestIndividual(pop))[fx.getD()])
{
best=Optimizer.getBestIndividual(pop);
error=pop.get(best)[fx.getD()];
}
r+=(double)P;
if(r>=reportFes)
{
r=0.0;
reports.add(new Report(pop, best, fes));
}
}
reports.add(new Report(pop, best, fes));
return reports;
}
}