00001 #include "AlgParticleSwarmOptimization.h"
00002
00003
00004 ParticleSwarmOptimization::ParticleSwarmOptimization()
00005 {
00006
00007 name_ = "ParticleSwarmOptimization";
00008
00009
00010
00011 selBestOp = static_cast<SelectionOperatorP> (new SelBestOp);
00012 }
00013
00014
00015
00016 void ParticleSwarmOptimization::registerParameters(StateP state)
00017 {
00018 registerParameter(state, "weightType", (voidP) new InertiaWeightType(CONSTANT), ECF::INT);
00019 registerParameter(state, "weight", (voidP) new double(0.8), ECF::DOUBLE);
00020 registerParameter(state, "maxVelocity", (voidP) new double(10.0), ECF::DOUBLE);
00021 registerParameter(state, "particleCount", (voidP) new uint(10), ECF::INT);
00022 }
00023
00024
00025 bool ParticleSwarmOptimization::initialize(StateP state)
00026 {
00027
00028 selBestOp->initialize(state);
00029
00030 voidP weightType = getParameterValue(state, "weightType");
00031 m_weightType = *((InertiaWeightType*) weightType.get());
00032
00033 voidP weight = getParameterValue(state, "weight");
00034 m_weight = *((double*) weight.get());
00035
00036 voidP maxV = getParameterValue(state, "maxVelocity");
00037 m_maxV = *((double*) maxV.get());
00038
00039
00040 if(m_weightType == TIME_VARIANT) {
00041 if(state->getRegistry()->isModified("term.maxgen")) {
00042
00043 m_maxIter = *(boost::static_pointer_cast<int>( state->getRegistry()->getEntry("term.maxgen") ));
00044 }
00045 else {
00046 ECF_LOG_ERROR(state, "Error: term.maxgen has to be specified in order to use time variant inertia eight in PSO algorithm");
00047 throw("");
00048 }
00049 }
00050
00051
00052 FloatingPointP flp (new FloatingPoint::FloatingPoint);
00053 if(state->getGenotypes()[0]->getName() != flp->getName()
00054 || state->getGenotypes().size() != 1) {
00055 ECF_LOG_ERROR(state, "Error: PSO algorithm accepts only a single FloatingPoint genotype!");
00056 throw ("");
00057 }
00058
00059 voidP sptr = state->getGenotypes()[0]->getParameterValue(state, "dimension");
00060 uint numDimension = *((uint*) sptr.get());
00061
00062 FloatingPointP flpoint[4];
00063 for(uint iGen = 1; iGen < 4; iGen++) {
00064
00065 flpoint[iGen] = (FloatingPointP) new FloatingPoint::FloatingPoint;
00066 state->setGenotype(flpoint[iGen]);
00067
00068 if(iGen == 3)
00069 flpoint[iGen]->setParameterValue(state, "dimension", (voidP) new uint(1));
00070 else
00071 flpoint[iGen]->setParameterValue(state, "dimension", (voidP) new uint(numDimension));
00072
00073
00074 flpoint[iGen]->setParameterValue(state, "lbound", (voidP) new double(0));
00075 flpoint[iGen]->setParameterValue(state, "ubound", (voidP) new double(1));
00076 }
00077 ECF_LOG(state, 1, "PSO algorithm: added 3 FloatingPoint genotypes (particle velocity, best-so-far postition, best-so-far fitness value)");
00078
00079 return true;
00080 }
00081
00082
00083 bool ParticleSwarmOptimization::advanceGeneration(StateP state, DemeP deme)
00084 {
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099 for( uint i = 0; i < deme->getSize(); i++ ) {
00100 IndividualP particle = deme->at(i);
00101
00102
00103 FloatingPointP flp = boost::dynamic_pointer_cast<FloatingPoint::FloatingPoint> (particle->getGenotype(3));
00104 double &particlePbestFitness = flp->realValue[0];
00105 double fitness = particle->fitness->getValue();
00106
00107 flp = boost::dynamic_pointer_cast<FloatingPoint::FloatingPoint> (particle->getGenotype(0));
00108 std::vector< double > &positions = flp->realValue;
00109
00110 flp = boost::dynamic_pointer_cast<FloatingPoint::FloatingPoint> (particle->getGenotype(2));
00111 std::vector< double > &pbestx = flp->realValue;
00112
00113
00114 if( fitness < particlePbestFitness ) {
00115 particlePbestFitness = fitness;
00116
00117
00118 for( uint j = 0;j<pbestx.size();j++ ) {
00119 pbestx[j] = positions[j];
00120 }
00121 }
00122
00123 }
00124
00125
00126 for( uint i = 0; i < deme->getSize(); i++ ) {
00127 IndividualP particle = deme->at(i);
00128
00129 IndividualP bestParticle = selBestOp->select( *deme );
00130
00131 FloatingPointP flp = boost::dynamic_pointer_cast<FloatingPoint::FloatingPoint> (particle->getGenotype(0));
00132 std::vector< double > &positions = flp->realValue;
00133
00134 flp = boost::dynamic_pointer_cast<FloatingPoint::FloatingPoint> (particle->getGenotype(1));
00135 std::vector< double > &velocities = flp->realValue;
00136
00137 flp = boost::dynamic_pointer_cast<FloatingPoint::FloatingPoint> (particle->getGenotype(2));
00138 std::vector< double > &pbestx = flp->realValue;
00139
00140
00141 double weight_up;
00142
00143 switch( m_weightType )
00144 {
00145
00146 case TIME_VARIANT:
00147 weight_up = ( m_weight - 0.4 ) * ( m_maxIter - state->getGenerationNo() ) / m_maxIter + 0.4;
00148 break;
00149
00150
00151 case CONSTANT:
00152 default:
00153 weight_up = m_weight;
00154 break;
00155 }
00156
00157 flp = boost::dynamic_pointer_cast<FloatingPoint::FloatingPoint> (bestParticle->getGenotype(2));
00158 std::vector< double > &bestParticlesPbestx = flp->realValue;
00159 for( uint j = 0; j < velocities.size(); j++ ) {
00160 double velocity;
00161
00162 velocity = weight_up * velocities[j] +
00163 2 * (rand()/(float)RAND_MAX) * (pbestx[j] - positions[j]) +
00164 2 * (rand()/(float)RAND_MAX) * (bestParticlesPbestx[j] - positions[j]);
00165 if( velocity > m_maxV ) velocity = m_maxV;
00166 velocities[j] = velocity;
00167
00168 positions[j] += velocities[j];
00169
00170 }
00171
00172
00173 evaluate( particle );
00174 }
00175
00176 return true;
00177 }