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 BinaryP bin = (BinaryP) new Binary::Binary;
00053 if(state->getGenotypes()[0]->getName() != bin->getName()
00054 || state->getGenotypes().size() != 1) {
00055 ECF_LOG_ERROR(state, "Error: PSO algorithm accepts only a single Binary genotype!");
00056 throw ("");
00057 }
00058
00059 voidP sptr = state->getGenotypes()[0]->getParameterValue(state, "dimension");
00060 uint numDimension = *((uint*) sptr.get());
00061
00062 BinaryP binary[4];
00063 for(uint iGen = 1; iGen < 4; iGen++) {
00064
00065 binary[iGen] = (BinaryP) new Binary::Binary;
00066 state->setGenotype(binary[iGen]);
00067
00068 if(iGen == 3)
00069 binary[iGen]->setParameterValue(state, "dimension", (voidP) new uint(1));
00070 else
00071 binary[iGen]->setParameterValue(state, "dimension", (voidP) new uint(numDimension));
00072
00073
00074 binary[iGen]->setParameterValue(state, "lbound", (voidP) new double(0));
00075 binary[iGen]->setParameterValue(state, "ubound", (voidP) new double(1));
00076 binary[iGen]->setParameterValue(state, "precision", (voidP) new uint(1));
00077 }
00078 ECF_LOG(state, 1, "PSO algorithm: added 3 Binary genotypes (particle velocity, best-so-far postition, best-so-far fitness value)");
00079
00080 return true;
00081 }
00082
00083
00084 bool ParticleSwarmOptimization::advanceGeneration(StateP state, DemeP deme)
00085 {
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100 for( uint i = 0; i < deme->getSize(); i++ ) {
00101 IndividualP particle = deme->at(i);
00102
00103
00104 BinaryP bin = boost::dynamic_pointer_cast<Binary::Binary> (particle->getGenotype(3));
00105 double &particlePbestFitness = bin->realValue[0];
00106 double fitness = particle->fitness->getValue();
00107
00108 bin = boost::dynamic_pointer_cast<Binary::Binary> (particle->getGenotype(0));
00109 std::vector< double > &positions = bin->realValue;
00110
00111 bin = boost::dynamic_pointer_cast<Binary::Binary> (particle->getGenotype(2));
00112 std::vector< double > &pbestx = bin->realValue;
00113
00114
00115 if( fitness < particlePbestFitness ) {
00116 particlePbestFitness = fitness;
00117
00118
00119 for( uint j = 0;j<pbestx.size();j++ ) {
00120 pbestx[j] = positions[j];
00121 }
00122 }
00123
00124 }
00125
00126
00127 for( uint i = 0; i < deme->getSize(); i++ ) {
00128 IndividualP particle = deme->at(i);
00129
00130 IndividualP bestParticle = selBestOp->select( *deme );
00131
00132 BinaryP bin = boost::dynamic_pointer_cast<Binary::Binary> (particle->getGenotype(0));
00133 std::vector< double > &positions = bin->realValue;
00134
00135 bin = boost::dynamic_pointer_cast<Binary::Binary> (particle->getGenotype(1));
00136 std::vector< double > &velocities = bin->realValue;
00137
00138 bin = boost::dynamic_pointer_cast<Binary::Binary> (particle->getGenotype(2));
00139 std::vector< double > &pbestx = bin->realValue;
00140
00141
00142 double weight_up;
00143
00144 switch( m_weightType )
00145 {
00146
00147 case TIME_VARIANT:
00148 weight_up = ( m_weight - 0.4 ) * ( m_maxIter - state->getGenerationNo() ) / m_maxIter + 0.4;
00149 break;
00150
00151
00152 case CONSTANT:
00153 default:
00154 weight_up = m_weight;
00155 break;
00156 }
00157
00158 bin = boost::dynamic_pointer_cast<Binary::Binary> (bestParticle->getGenotype(2));
00159 std::vector< double > &bestParticlesPbestx = bin->realValue;
00160 for( uint j = 0; j < velocities.size(); j++ ) {
00161 double velocity;
00162
00163 velocity = weight_up * velocities[j] +
00164 2 * (rand()/(float)RAND_MAX) * (pbestx[j] - positions[j]) +
00165 2 * (rand()/(float)RAND_MAX) * (bestParticlesPbestx[j] - positions[j]);
00166 if( velocity > m_maxV ) velocity = m_maxV;
00167 velocities[j] = velocity;
00168
00169 positions[j] += velocities[j];
00170
00171 }
00172
00173
00174 evaluate( particle );
00175 }
00176
00177 return true;
00178 }