/* Copyright 2006 by Ankur Desai, Sean Luke, and George Mason University Licensed under the Academic Free License version 3.0 See the file "LICENSE" for more information */ package sim.app.pso; import sim.util.Double2D; import sim.util.MutableDouble2D; /** @author Ankur Desai and Joey Harrison */ public class Particle { private static final long serialVersionUID = 1; double bestVal = 0; MutableDouble2D bestPosition = new MutableDouble2D(); MutableDouble2D position = new MutableDouble2D(); MutableDouble2D velocity = new MutableDouble2D(); PSO pso; Evaluatable fitnessFunction; int index; // this kludge is necessary because the particles are individually scheduled public Particle() { super(); } public Particle(double x, double y, double vx, double vy, PSO pso, Evaluatable f, int index) { super(); this.position.setTo(x, y); this.velocity.setTo(vx, vy); this.pso = pso; this.fitnessFunction = f; pso.space.setObjectLocation(this,new Double2D(position)); this.index = index; } public void updateBest(double currVal, double currX, double currY) { if (currVal > bestVal) { bestVal = currVal; bestPosition.setTo(currX, currY); pso.updateBest(currVal, currX, currY); } } public double getFitness() { return fitnessFunction.calcFitness(position.x,position.y); } public void stepUpdateFitness() { updateBest(getFitness(), position.x, position.y); } public void stepUpdateVelocity() { double x = position.x; double y = position.y; MutableDouble2D nBestPos = new MutableDouble2D(); pso.getNeighborhoodBest(index, nBestPos); // updates the location of nBestPos // calc new velocity // calc x component double inertia = velocity.x; double pDelta = bestPosition.x - x; double nDelta = nBestPos.x - x; double gDelta = pso.bestPosition.x - x; double pWeight = Math.random() + 0.4; double nWeight = Math.random() + 0.4; double gWeight = Math.random() + 0.4; double vx = (0.9*inertia + pWeight*pDelta + nWeight*nDelta + gWeight*gDelta) / (1+pWeight+nWeight+gWeight); // calc y component inertia = velocity.y; pDelta = bestPosition.y - y; nDelta = nBestPos.y - y; gDelta = pso.bestPosition.y - y; pWeight = Math.random() + 0.4; nWeight = Math.random() + 0.4; gWeight = Math.random() + 0.4; double vy = (0.9*inertia + pWeight*pDelta + nWeight*nDelta + gWeight*gDelta) / (1+pWeight+nWeight+gWeight); vx *= pso.velocityScalar; vy *= pso.velocityScalar; // update velocity velocity.setTo(vx, vy); } public void stepUpdatePosition() { //System.out.println( // "Best: " + n.bestVal + " (" + n.bestPosition.x + ", " + n.bestPosition.y + ")"); position.addIn(velocity); pso.space.setObjectLocation(this, new Double2D(position)); } }