ECF 1.5
AlgParticleSwarmOptimization.cpp
1#include "AlgParticleSwarmOptimization.h"
2
3
4ParticleSwarmOptimization::ParticleSwarmOptimization()
5{
6 // define algorithm name
7 name_ = "ParticleSwarmOptimization";
8
9 areGenotypesAdded_ = false;
10
11 // create selection operators needed
12 // in this case, SelBestOp
13 selBestOp = static_cast<SelectionOperatorP> (new SelBestOp);
14}
15
16
17// register algorithm parameters
19{
20 registerParameter(state, "weightType", (voidP) new InertiaWeightType(CONSTANT), ECF::INT,
21 "weight type update: 0 - constant, 1 - time dependant (based on max generations)");
22 registerParameter(state, "weight", (voidP) new double(0.8), ECF::DOUBLE,
23 "initial inertia weight (either constant or time dependant)");
24 registerParameter(state, "maxVelocity", (voidP) new double(10.0), ECF::DOUBLE,
25 "max particle velocity");
26 registerParameter(state, "bounded", (voidP) new uint(0), ECF::UINT,
27 "should the algorithm respect the bounds defined in the genotype or not (default: 0)");
28}
29
30
32{
33 // initialize all operators
34 selBestOp->initialize(state);
35
36 voidP weightType = getParameterValue(state, "weightType");
37 m_weightType = *((InertiaWeightType*) weightType.get());
38
39 voidP weight = getParameterValue(state, "weight");
40 m_weight = *((double*) weight.get());
41
42 voidP maxV = getParameterValue(state, "maxVelocity");
43 m_maxV = *((double*) maxV.get());
44
45 // test if inertia weight type is time variant and if so, check if max iterations specified
46 if(m_weightType == TIME_VARIANT) {
47 if(state->getRegistry()->isModified("term.maxgen")) {
48 // read maxgen parameter
49 m_maxIter = *(boost::static_pointer_cast<int>( state->getRegistry()->getEntry("term.maxgen") ));
50 }
51 else {
52 ECF_LOG_ERROR(state, "Error: term.maxgen has to be specified in order to use time variant inertia eight in PSO algorithm");
53 throw("");
54 }
55 }
56
57 // algorithm accepts a single FloatingPoint or Binary genotype
58 // or a genotype derived from the abstract RealValueGenotype class
59 GenotypeP activeGenotype = state->getGenotypes()[0];
60 RealValueGenotypeP rv = boost::dynamic_pointer_cast<RealValueGenotype> (activeGenotype);
61 if(!rv || state->getGenotypes().size() > 1) {
62 ECF_LOG_ERROR(state, "Error: PSO algorithm accepts only a RealValueGenotype derived genotype! (FloatingPoint or Binary)");
63 throw ("");
64 }
65
66 voidP sptr = state->getGenotypes()[0]->getParameterValue(state, "dimension");
67 uint numDimension = *((uint*) sptr.get());
68
69 voidP bounded = getParameterValue(state, "bounded");
70 bounded_ = *((bool*) bounded.get());
71
72 sptr = state->getGenotypes()[0]->getParameterValue(state, "lbound");
73 lbound_ = *((double*) sptr.get());
74
75 sptr = state->getGenotypes()[0]->getParameterValue(state, "ubound");
76 ubound_ = *((double*) sptr.get());
77
78 // batch run check
79 if(areGenotypesAdded_)
80 return true;
81
82 FloatingPointP flpoint[4];
83 for(uint iGen = 1; iGen < 4; iGen++) {
84
85 flpoint[iGen] = (FloatingPointP) new FloatingPoint::FloatingPoint;
86 state->setGenotype(flpoint[iGen]);
87
88 if(iGen == 3)
89 flpoint[iGen]->setParameterValue(state, "dimension", (voidP) new uint(1));
90 else
91 flpoint[iGen]->setParameterValue(state, "dimension", (voidP) new uint(numDimension));
92
93 // other parameters are proprietary (ignored by the algorithm)
94 flpoint[iGen]->setParameterValue(state, "lbound", (voidP) new double(0));
95 flpoint[iGen]->setParameterValue(state, "ubound", (voidP) new double(1));
96 }
97 ECF_LOG(state, 1, "PSO algorithm: added 3 FloatingPoint genotypes (particle velocity, best-so-far postition, best-so-far fitness value)");
98
99 // mark adding of genotypes
100 areGenotypesAdded_ = true;
101
102 return true;
103}
104
105
107{
108// a) For each particle:
109// 1) If the fitness value is better than the best fitness value (pBest) in history
110// 2) Set current value as the new pBest
111// End
112// b) For each particle:
113// 1) Find, in the particle neighborhood, the particle with the best fitness
114// 2) Calculate particle velocity according to the velocity equation (1)
115// 3) Apply the velocity constriction
116// 4) Update particle position according to the position equation (2)
117// 5) Apply the position constriction
118// 6) Calculate fitness value
119// End
120
121 // a)
122 for( uint i = 0; i < deme->getSize(); i++ ) { // for each particle
123 IndividualP particle = deme->at(i);
124
125 // the whole point of this section is to compare fitness and pbest
126 FloatingPointP flp = boost::static_pointer_cast<FloatingPoint::FloatingPoint> (particle->getGenotype(3));
127 double &particlePbestFitness = flp->realValue[0];
128 double fitness = particle->fitness->getValue();
129
130 flp = boost::static_pointer_cast<FloatingPoint::FloatingPoint> (particle->getGenotype(0));
131 std::vector< double > &positions = flp->realValue;
132
133 flp = boost::static_pointer_cast<FloatingPoint::FloatingPoint> (particle->getGenotype(2));
134 std::vector< double > &pbestx = flp->realValue;
135
136 // set particle pbestx-es
137 if( /*iter == 0 ||*/ fitness < particlePbestFitness ) { // minimize error
138 particlePbestFitness = fitness;
139
140 // set pbestx-es
141 for( uint j = 0;j<pbestx.size();j++ ) {
142 pbestx[j] = positions[j];
143 }
144 }
145 // NOTE store best particle index?
146 }
147
148 // b)
149 for( uint i = 0; i < deme->getSize(); i++ ) { // for each particle
150 IndividualP particle = deme->at(i);
151
152 IndividualP bestParticle = selBestOp->select( *deme );
153
154 FloatingPointP flp = boost::static_pointer_cast<FloatingPoint::FloatingPoint> (particle->getGenotype(0));
155 std::vector< double > &positions = flp->realValue;
156
157 flp = boost::static_pointer_cast<FloatingPoint::FloatingPoint> (particle->getGenotype(1));
158 std::vector< double > &velocities = flp->realValue;
159
160 flp = boost::static_pointer_cast<FloatingPoint::FloatingPoint> (particle->getGenotype(2));
161 std::vector< double > &pbestx = flp->realValue;
162
163
164 double weight_up;
165
166 switch( m_weightType )
167 {
168 //time variant weight, linear from weight to 0.4
169 case TIME_VARIANT:
170 weight_up = ( m_weight - 0.4 ) * ( m_maxIter - state->getGenerationNo() ) / m_maxIter + 0.4;
171 break;
172
173 // constant inertia weight
174 case CONSTANT:
175 default:
176 weight_up = m_weight;
177 break;
178 }
179 // calculate particle velocity according to the velocity equation (1)
180 flp = boost::static_pointer_cast<FloatingPoint::FloatingPoint> (bestParticle->getGenotype(2));
181 std::vector< double > &bestParticlesPbestx = flp->realValue;
182 for( uint j = 0; j < velocities.size(); j++ ) {
183 double velocity;
184
185 velocity = weight_up * velocities[j] +
186 2 * (rand()/(float)RAND_MAX) * (pbestx[j] - positions[j]) +
187 2 * (rand()/(float)RAND_MAX) * (bestParticlesPbestx[j] - positions[j]);
188 if( velocity > m_maxV ) velocity = m_maxV;
189 velocities[j] = velocity;
190
191 positions[j] += velocities[j];
192 // TODO apply position constriction
193
194 // check for bounds
195 if(bounded_) {
196 if(positions[j] < lbound_)
197 positions[j] = lbound_;
198 if(positions[j] > ubound_)
199 positions[j] = ubound_;
200 }
201 }
202
203 // determine new particle fitness
204 evaluate( particle );
205 }
206
207 return true;
208}
std::string name_
algorithm name
Definition: Algorithm.h:23
bool registerParameter(StateP state, std::string name, voidP value, enum ECF::type T, std::string description="")
Helper function: register a single parameter with the system.
Definition: Algorithm.h:35
voidP getParameterValue(StateP state, std::string name)
Helper function: get parameter value from the system.
Definition: Algorithm.h:46
void evaluate(IndividualP ind)
Helper function: evaluate an individual.
Definition: Algorithm.h:157
FloatingPoint class - implements genotype as a vector of floating point values.
Definition: FloatingPoint.h:39
bool setParameterValue(StateP state, std::string name, voidP value)
Write single parameter value to Registry.
Definition: Genotype.cpp:16
bool advanceGeneration(StateP state, DemeP deme)
Perform a single generation on a single deme.
void registerParameters(StateP state)
Register algorithm's parameters (if any).
bool initialize(StateP state)
Initialize the algorithm, read parameters from the system, do a sanity check.
Best individual selection operator.
Definition: SelBestOp.h:10