• Main Page
  • Modules
  • Classes
  • Files
  • File List

D:/Projekt/ECF_trunk/ECF/AlgParticleSwarmOptimization.cpp

00001 #include "AlgParticleSwarmOptimization.h"
00002 
00003 
00004 ParticleSwarmOptimization::ParticleSwarmOptimization()
00005 {
00006     // define algorithm name
00007     name_ = "ParticleSwarmOptimization";
00008 
00009     // create selection operators needed
00010     // in this case, SelBestOp
00011     selBestOp = static_cast<SelectionOperatorP> (new SelBestOp);
00012 }
00013 
00014 
00015 // register algorithm parameters
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     // initialize all operators
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     // test if inertia weight type is time variant and if so, check if max iterations specified
00040     if(m_weightType == TIME_VARIANT) {
00041         if(state->getRegistry()->isModified("term.maxgen")) {
00042             // read maxgen parameter
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     // algorithm accepts a single Binary Genotype (for now)
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         // other parameters are proprietary (ignored by the algorithm)
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 //       a) For each particle:
00087 //          1) If the fitness value is better than the best fitness value (pBest) in  history
00088 //          2) Set current value as the new pBest
00089 //          End
00090 //       b) For each particle:
00091 //          1) Find in the particle neighborhood, the particle with the best fitness
00092 //          2) Calculate particle velocity according to the velocity equation (1)
00093 //          3) Apply the velocity constriction
00094 //          4) Update particle position according to the position equation (2)
00095 //          5) Apply the position constriction
00096 //          6) Calculate fitness value
00097 //          End
00098 
00099     // a)
00100     for( uint i = 0; i < deme->getSize(); i++ ) { // for each particle 
00101         IndividualP particle = deme->at(i);
00102 
00103         // the whole point of this section is to compare fitness and pbest
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         // set particle pbestx-es
00115         if( /*iter == 0 ||*/ fitness < particlePbestFitness ) { // minimize error
00116             particlePbestFitness = fitness;
00117 
00118             // set pbestx-es
00119             for( uint j = 0;j<pbestx.size();j++ ) {
00120                 pbestx[j] = positions[j];
00121             }
00122         }
00123         // NOTE store best particle index?
00124     }
00125 
00126     // b)
00127     for( uint i = 0; i < deme->getSize(); i++ ) { // for each particle
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             //time variant weight, linear from weight to 0.4
00147             case TIME_VARIANT:
00148             weight_up = ( m_weight - 0.4 ) * ( m_maxIter - state->getGenerationNo() ) / m_maxIter + 0.4;
00149             break;
00150 
00151             // constant inertia weight
00152             case CONSTANT:
00153             default:
00154             weight_up = m_weight;
00155             break;
00156         }
00157         // calculate particle velocity according to the velocity equation (1)
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             // TODO apply position constriction
00171         }
00172 
00173         // determine new particle fitness
00174         evaluate( particle );
00175     }
00176 
00177     return true;
00178 }

Generated on Thu Oct 6 2011 13:40:59 for ECF by  doxygen 1.7.1