package gannuOP.algorithms.single_point;
import gannuOP.algorithms.Optimizer;
import gannuOP.testing.Function;
import gannuOP.testing.Report;
import java.util.ArrayList;
public class PS extends Optimizer {
@Override
public ArrayList<Report> solve(String parameters, Function fx,
double maxFes, double reportFes, double precision) throws Exception {
int R=0;
double error;
int best;
double B=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("R="))
{
R=Integer.parseInt(parameter.replace("R=", ""));
}
if(parameter.startsWith("B="))
{
B=Double.parseDouble(parameter.replace("B=", ""));
}
}
//Initialization of population
ArrayList<double []> pop=new ArrayList<double []>(1);
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 fes;
double []b=new double[fx.getD()];
double []xbest=new double[fx.getD()+1];
for(int j=0;j<fx.getD();j++)
b[j]=B;
// int c=1;
best=Optimizer.getBestIndividual(pop);
for(int j=0;j<fx.getD()+1;j++)
{
xbest[j]=pop.get(best)[j];
}
error=pop.get(best)[fx.getD()];
double r=0.0;
int restart=0;
/* FileWriter of=null;
BufferedWriter out = null;
try
{
of=new FileWriter(fx.toString()+".R");
out=new BufferedWriter(of);
out.write(fx.toRplot(precision));
}catch(Exception e)
{
}*/
for(fes=(double)1;fes<maxFes&&error>=precision;fes+=(double)1)
{
double u[]=new double[fx.getD()+1];
double pa=((double)Optimizer.rnd(1, fx.getD()))/((double)fx.getD());
for(int j=0;j<fx.getD();j++)
{
if(Optimizer.rndreal(0, 1.0)<=pa)
{
u[j]=pop.get(0)[j]+Optimizer.rndreal(-b[j], b[j])*(fx.getLimit()[1][j]-fx.getLimit()[0][j]);
if(u[j]<fx.getLimit()[0][j])
u[j]=fx.getLimit()[1][j]-(fx.getLimit()[0][j]-u[j]);
if(u[j]>fx.getLimit()[1][j])
u[j]=fx.getLimit()[0][j]+(u[j]-fx.getLimit()[1][j]);
}
else
{
u[j]=pop.get(0)[j];
}
}
u[fx.getD()]=fx.evaluate(u);
//Replacement
if(u[fx.getD()]<pop.get(0)[fx.getD()])
{
restart=0;
for(int j=0;j<fx.getD();j++)
{
if(pop.get(0)[j]!=u[j])
b[j]=Optimizer.rndreal(b[j],B);
pop.get(0)[j]=u[j];
}
pop.get(0)[fx.getD()]=u[fx.getD()];
if(u[fx.getD()]<error)
{
for(int j=0;j<(fx.getD()+1);j++)
{
xbest[j]=u[j];
}
error=u[fx.getD()];
}
}
else
{
restart++;
if(restart<R)
{
for(int j=0;j<fx.getD();j++)
{
if(pop.get(0)[j]!=u[j])
{
b[j]=Math.abs((pop.get(0)[j]-u[j])/(fx.getLimit()[1][j]-fx.getLimit()[0][j]));
}
}
}
else
{
restart=0;
for(int j=0;j<fx.getD();j++)
{
b[j]=B;
pop.get(0)[j]=u[j];
}
pop.get(0)[fx.getD()]=u[fx.getD()];
}
}
r+=1.0;
if(r>=reportFes)
{
r=0.0;
reports.add(new Report(pop, best, fes));
}
/* try
{
if(fx.getD()==1)
{
out.write("plot(x,y,type='l')\n");
out.write("points("+xbest[0]+","+xbest[1]+",pch=4,cex=2)\n");
out.write("points("+pop.get(0)[0]+","+pop.get(0)[1]+",pch=19,cex=1.5)\n");
out.write("points("+u[0]+","+u[1]+",pch=19,cex=1.1,col='red',bg='red')\n");
//out.write("dev.copy(png,'"+String.valueOf(fes).substring(0,String.valueOf(fes).indexOf("."))+".png')\n");
String format = String.format("%%0%dd", 4);
String result = String.format(format,Integer.parseInt(String.valueOf(fes).substring(0,String.valueOf(fes).indexOf("."))));
out.write("savePlot(filename='plot/"+result+"', type='jpeg')\n");
}
if(fx.getD()==2)
{
out.write("res<-persp(x,y,z,theta=30,phi=40)\n");
out.write("points(trans3d("+xbest[0]+","+xbest[1]+","+xbest[2]+",res),pch=4,cex=2)\n");
out.write("points(trans3d("+pop.get(0)[0]+","+pop.get(0)[1]+","+pop.get(0)[2]+",res),pch=19,cex=1.5)\n");
out.write("points(trans3d("+u[0]+","+u[1]+","+u[2]+",res),pch=19,cex=1.1,col='red',bg='red')\n");
//out.write("dev.copy(png,'"+String.valueOf(fes).substring(0,String.valueOf(fes).indexOf("."))+".png')\n");
String format = String.format("%%0%dd", 4);
String result = String.format(format,Integer.parseInt(String.valueOf(fes).substring(0,String.valueOf(fes).indexOf("."))));
out.write("savePlot(filename='plot/"+result+"', type='jpeg')\n");
}
}
catch(Exception e)
{
System.out.println(e.getMessage());
}*/
if(error<precision)
{
System.out.println(fx.evaluate(xbest));
}
}
reports.add(new Report(pop, best, fes));
/*try{
out.close();
of.close();
}
catch(Exception e)
{
}*/
return reports;
}
}