我正在用Java制作一个PSO,并且大部分都完成了,但是它的表现根本不符合预期,尤其是在gBest,pBest和粒子速度更新方面
我尝试了多种存储/计算gBest和pBest以及速度更新的方法,但是由于某种原因,我无法弄清一切似乎都收敛于0。我将Swarm和Particle类附加为我认为问题必须出在这里。
群类:
public class Swarm {
FunctionChoices function;
int numberOfParticles;
int numberOfIterations;
ArrayList<Particle> particles;
double gBest = Double.POSITIVE_INFINITY;
Vector gBestLocation;
double inertia = 0.729844;
double social = 1.496180;
public Swarm(FunctionChoices function, int numberOfParticles, int numberOfIterations) {
this.function = function;
this.numberOfParticles = numberOfParticles;
this.numberOfIterations = numberOfIterations;
particles = new ArrayList<Particle>();
gBestLocation = new Vector(0, 0, 0);
execute();
}
private void execute() {
//Particle particle;
for(int i = 0; i < numberOfParticles; i++) {
Particle particle = new Particle(function);
particles.add(particle);
updateGBest(particle);
}
double oldGBest = gBest;
System.out.println("--------------------------EXECUTING-------------------------");
System.out.println("Global Best Evaluation (Iteration " + 0 + "):\t" + gBest);
for(int i = 0; i < numberOfIterations; i++) {
if(gBest < oldGBest) {
System.out.println("Global Best Evaluation (Iteration " + (i + 1) + "):\t" + gBest);
oldGBest = gBest;
}
for(int j = 0; j < particles.size(); j++) {
//System.out.println("old pBest = " + particles.get(j).getPBest());
particles.get(j).updatePBest(particles.get(j));
//System.out.println("new pBest = " + particles.get(j).getPBest());
//System.out.println("old gBest: " + gBest);
updateGBest(particles.get(j));
//System.out.println("new gBest: " + gBest);
}
for(int j = 0; j < particles.size(); j++) {
//System.out.println("Old position: " + particles.get(j).getLocation());
updateVelocity(particles.get(j));
particles.get(j).updateLocation();
//System.out.println("New position: " + particles.get(j).getLocation());
}
}
System.out.println("---------------------------RESULT---------------------------");
System.out.println("x = " + gBestLocation.getX());
System.out.println("Final Best Evaluation: " + gBest);
System.out.println("---------------------------COMPLETE-------------------------");
}
private void updateGBest(Particle particle) {
if(particle.getPBest() < gBest) {
gBest = particle.getPBest();
gBestLocation = particle.getPBestLocation();
}
}
private void updateVelocity(Particle particle) {
Vector oldVelocity = particle.getVelocity();
Vector pBest = particle.getPBestLocation();
System.out.println("pBest: " + pBest);
Vector gBest = gBestLocation;
Vector currentLocation = particle.getLocation();
System.out.println("cL: " + currentLocation);
Random random = new Random();
double r1 = random.nextDouble();
double r2 = random.nextDouble();
Vector newVelocity = oldVelocity;
newVelocity.multiply(inertia);
System.out.println("New Velocity1: " + newVelocity);
pBest.subtract(currentLocation);
pBest.multiply(social);
pBest.multiply(r1);
newVelocity.add(pBest);
System.out.println("pBest: " + pBest);
System.out.println("New Velocity2: " + newVelocity);
gBest.subtract(currentLocation);
gBest.multiply(social);
gBest.multiply(r2);
newVelocity.add(gBest);
System.out.println("New Velocity3: " + newVelocity);
particle.setVelocity(newVelocity);
}
}
粒子类:
public class Particle {
private FunctionChoices function;
private Vector location;
private Vector velocity;
double minRange = -100;
double maxRange = 101;
private double pBest;
private Vector pBestLocation;
public Particle(FunctionChoices function) {
this.function = function;
location = new Vector(0, 0, 0);
velocity = new Vector(0, 0, 0);
pBestLocation = new Vector(0, 0, 0);
setInitialPosition();
pBest = getInitialPBest();
}
private void setInitialPosition() {
double x = ThreadLocalRandom.current().nextDouble(minRange, maxRange);
double y = ThreadLocalRandom.current().nextDouble(minRange, maxRange);
double z = ThreadLocalRandom.current().nextDouble(minRange, maxRange);
location.setLocation(x, y, z);
}
private double getInitialPBest() {
if(function == FunctionChoices.testFunction1) {
pBestLocation = location;
return Functions.testFunction1(location.getX());
}
else if(function == FunctionChoices.testFunction2) {
pBestLocation = location;
return Functions.testFunction2(location.getX());
}
else {
return 0;
}
}
private double getFitness() {
if(function == FunctionChoices.testFunction1) {
return Functions.testFunction1(location.getX());
}
else if(function == FunctionChoices.testFunction2) {
return Functions.testFunction2(location.getX());
}
else {
return 0;
}
}
public void updatePBest(Particle particle) {
double currentFitness = getFitness();
if(currentFitness < particle.getPBest()) {
pBest = currentFitness;
pBestLocation = location;
}
}
public double getPBest() {
return pBest;
}
public Vector getPBestLocation() {
return pBestLocation;
}
public Vector getLocation() {
return location;
}
public Vector getVelocity() {
return velocity;
}
public void setVelocity(Vector velocity) {
this.velocity = velocity;
}
public void updateLocation() {
this.location.add(velocity);
}
}