我正在制作粒子群优化器(PSO),它已经完成并可以运行,但是粒子的位置和gBest的位置似乎存在问题。
当我运行诸如X ^ 4-2X ^ 3之类的函数时,我的PSO将给我最终的gBest值,约为-1.68,该值已经足够接近,但是对应的位置将不正确,它应该给我一个x-值大约为1.5,但它将返回0到1.5之间的任何值。我尝试了许多不同的方法来更新粒子的速度和位置,但是我现在拥有的方法是迄今为止迄今为止最好的方法。我不确定为什么这些位置无法正常工作,因此不胜感激。
我已经附加了Particle,Swarm和Vector类,因为我认为问题一定在这里。
向量类: 公共类Vector {
double x, y, z;
public Vector(double x, double y, double z) {
this.x = x;
this.y = y;
this.z = z;
}
public void setLocation(double x, double y, double z) {
setX(x);
setY(y);
setZ(z);
}
private void setX(double x) {
this.x = x;
}
private void setY(double y) {
this.y = y;
}
private void setZ(double z) {
this.z = z;
}
public String toString() {
return "x: " + x + " Y: " + y + " Z: " + z;
}
public double getX() {
return x;
}
public double getY() {
return y;
}
public void multiply(double d) {
x *= d;
y *= d;
z *= d;
}
public void subtract(Vector v) {
x -= v.x;
y -= v.y;
z -= v.z;
}
public void add(Vector v) {
x += v.x;
y += v.y;
z += v.z;
}
}
粒子类: 公共类粒子{
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);
}
}
群类: 公共类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;
double inertiaTest = 0.36;
double socialTest = 075;
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("Particle " + j + " Old position: " + particles.get(j).getLocation());
updateVelocity(particles.get(j));
particles.get(j).updateLocation();
System.out.println("Particle " + j + " New position: " + particles.get(j).getLocation());
}
}
System.out.println("---------------------------RESULT---------------------------");
System.out.println("x = " + gBestLocation.getX());
System.out.println("y = " + gBestLocation.getY());
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(inertiaTest);
//System.out.println("New Velocity1: " + newVelocity);
pBest.subtract(currentLocation);
pBest.multiply(socialTest);
pBest.multiply(r1);
newVelocity.add(pBest);
//System.out.println("pBest: " + pBest);
//System.out.println("New Velocity2: " + newVelocity);
gBest.subtract(currentLocation);
gBest.multiply(socialTest);
gBest.multiply(r2);
newVelocity.add(gBest);
//System.out.println("New Velocity3: " + newVelocity);
particle.setVelocity(newVelocity);
}
}