📄 swarm.java
字号:
/* * Swarm.java * * This is a required part of the com.adaptiveview.ospso package. * * Copyright (C) 2003 AdaptiveView.com * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * You may contact AdaptiveView.com via email at: comments.pso@adaptiveview.com * */package com.adaptiveview.ospso;import com.adaptiveview.toolkits.numbers.*;/**The Swarm is a collection of particles that are moved through a solution space; * the Swarm's <code>iterate</code> method is used to initiate * particle movement. The <code>iterate</code> method: *<blockquote> * a) First sends every particle a <code>calculateNextLocation</code> message.<p> * b) It then sends every particle an <code>updateCurrentLocation</code> message (making the calculated next position the current position).<p> * c) Then it evaluates the fitness of every particle's new current position and: *<blockquote> * 1) If, after all fitness values are calulated, at least one fitness is within the range * defined by a specified ConstraintSet the <code>iterate</code> method returns true.<p> * 2) Otherwise, the <code>iterate</code> method returns false. *</blockquote> *</blockquote> * * @author AdaptiveView.com */public class Swarm implements com.adaptiveview.ospso.dmi.DMI_GPL_License { private int numberOfParticles = 0; private int nextParticleIndex = 0; private IFitnessAlgorithm fitnessAlgorithm; private double globalBestFitness = Double.NEGATIVE_INFINITY; private INeighborhoodTopology neighborhoodTopology; private Particle[] particles; /** Creates a new instance of Swarm *@param numberOfParticles how many particles in the swarm. <b>Note</b> that * all particles must be <code>add</code>ed before the <code>iterate</code> method will work. *@param fitnessAlgorithm the fitness algorithm to be used for all particles. *@param neighborhoodTopology the topology to be used for this swarm. */ public Swarm(int numberOfParticles, IFitnessAlgorithm fitnessAlgorithm, INeighborhoodTopology neighborhoodTopology) { this.numberOfParticles = numberOfParticles; this.particles = new Particle[numberOfParticles]; this.fitnessAlgorithm = fitnessAlgorithm; this.neighborhoodTopology = neighborhoodTopology; } /** Add new particles using same constraints and move algorithm. *@param count the number of particles to add using specified constraints and move algorithm. *@param constraintSet the ConstraintSet instance for each (every) particle added. *@param moveAlgorithm the IMoveAlgorithm instance for each (every) particle added. *@throws IllegalArgumentException if attempting to add less than one particle. */ public void addParticles(int count, ConstraintSet constraintSet, IMoveAlgorithm moveAlgorithm) throws IllegalArgumentException { if (count < 1) throw new IllegalArgumentException("Cannot add " + count + (count == -1 ? " particle." : " partcles.")); for (int i = 0; i < count; i++) { addParticle(constraintSet, moveAlgorithm); } } /**Add one new particle *@param constraintSet the ConstraintSet instance for the particle. *@param moveAlgorithm the IMoveAlgorithm instance for the particle. *@throws IllegalStateException if attempting to add too many particles. *@return the particle count following the add. */ public int addParticle(ConstraintSet constraintSet, IMoveAlgorithm moveAlgorithm) throws IllegalStateException { if (nextParticleIndex >= numberOfParticles) throw new IllegalStateException("All " + numberOfParticles + " particles already defined."); particles[nextParticleIndex] = new Particle(nextParticleIndex, constraintSet, moveAlgorithm); nextParticleIndex += 1; return nextParticleIndex; } /**Sets up the particles for the beginning of a swarm (run) by updating the * current location, setting the current location's fitness and, as this is * the first location, making it the best location (so far) -- this method * <b>must be invoked</b> before the move algorithm is used for the first time. */ public void setInitialFitnessValues() { int p; double fitness; for (p = 0; p < numberOfParticles; p++) { particles[p].updateCurrentLocation(); fitness = fitnessAlgorithm.calculateFitness(particles[p].getCurrentLocationChange()); particles[p].setCurrentLocationFitness(fitness); particles[p].setCurrentLocationAsBest(); } } /**Iterates a specified number of times through all particles in the Swarm, getting their next location, * making the next locations current and evaluating the fitness of the new * current location; returns <b>true</b> if any particle's fitness is within the * defined exit conditions, otherwise <b>false</b>. *@param numberOfIterations how many times to move particles. *@param exitCondition a range (Constraint) indicating an acceptable fitness value * after which the iterations can stop. <b>Note</b> that the iterate method will * <i>not</i> return until it has completed the current iteration for <i>all</i> particles. *@throws IllegalStateException if not all particles ahve been defined yet. *@return <b>true</b> if any particle's fitness is within the defined exit * conditions, otherwise <b>false</b> */ public boolean iterate(int numberOfIterations, Constraint exitCondition) throws IllegalStateException { if (nextParticleIndex < numberOfParticles) throw new IllegalStateException("Only " + nextParticleIndex + " of " + numberOfParticles + " particles defined."); double fitness, bestFitness; double exitConditionMin = exitCondition.getMinimum(); double exitConditionMax = exitCondition.getMaximum(); int p; // particle LocationChange currentLocation; for (int i = 0; i < numberOfIterations; i++) { // calculate the "next" location for (p = 0; p < numberOfParticles; p++) { particles[p].calculateNextLocation(getNeighborhoodBestLocation(p)); } // make the "next" location current for (p = 0; p < numberOfParticles; p++) { particles[p].updateCurrentLocation(); } // get the fitness and update best location if this fitness is // better than previous best. for (p = 0; p < numberOfParticles; p++) { bestFitness = particles[p].getBestLocationFitness(); currentLocation = particles[p].getCurrentLocationChange(); fitness = fitnessAlgorithm.calculateFitness(currentLocation); particles[p].setCurrentLocationFitness(fitness); if (fitness >= bestFitness) { particles[p].setCurrentLocationAsBest(); if (fitness > globalBestFitness) { globalBestFitness = fitness; /* =#==#==#==#==#==#==#==#==#==#==#==#==#==#==#==#==#==#==#==#==#==#==#==#==#==#==#= * begin removable code * =#==#==#==#==#==#==#==#==#==#==#==#==#==#==#==#==#==#==#==#==#==#==#==#==#==#==#= */System.out.print("At iteration " + i + " particle " + p + " now has global best fitness: (" + fitness + ") => ");System.out.println(particles[p].getCurrentLocationChange().toString());/* =#==#==#==#==#==#==#==#==#==#==#==#==#==#==#==#==#==#==#==#==#==#==#==#==#==#==#= * end removable code * =#==#==#==#==#==#==#==#==#==#==#==#==#==#==#==#==#==#==#==#==#==#==#==#==#==#==#= */ } } } // return true if the global best fitness is within the defined exit conditions if (Range.inRange(globalBestFitness, exitConditionMin, exitConditionMax)) return true; } // end of: for (int i = 0; i < numberOfIterations; i++) ... return false; } /* Given particle at index p in particles array, return the LocationChange * instance for that particle's neighborhood best. */ private LocationChange getNeighborhoodBestLocation(int p) { int[] neighbors; neighbors = neighborhoodTopology.getNeighborIDs(p); int n = neighbors.length; double bestSoFar = Double.NEGATIVE_INFINITY; double fitness; int bestNeighbor = 0; for (int i = 0; i < n; i++) { fitness = particles[i].getBestLocationFitness(); if (fitness > bestSoFar) { bestSoFar = fitness; bestNeighbor = i; } } return particles[bestNeighbor].getBestLocationChange(); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -