• 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 FloatingPoint Genotype
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         // other parameters are proprietary (ignored by the algorithm)
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 //       a) For each particle:
00086 //          1) If the fitness value is better than the best fitness value (pBest) in  history
00087 //          2) Set current value as the new pBest
00088 //          End
00089 //       b) For each particle:
00090 //          1) Find, in the particle neighborhood, the particle with the best fitness
00091 //          2) Calculate particle velocity according to the velocity equation (1)
00092 //          3) Apply the velocity constriction
00093 //          4) Update particle position according to the position equation (2)
00094 //          5) Apply the position constriction
00095 //          6) Calculate fitness value
00096 //          End
00097 
00098     // a)
00099     for( uint i = 0; i < deme->getSize(); i++ ) { // for each particle 
00100         IndividualP particle = deme->at(i);
00101 
00102         // the whole point of this section is to compare fitness and pbest
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         // set particle pbestx-es
00114         if( /*iter == 0 ||*/ fitness < particlePbestFitness ) { // minimize error
00115             particlePbestFitness = fitness;
00116 
00117             // set pbestx-es
00118             for( uint j = 0;j<pbestx.size();j++ ) {
00119                 pbestx[j] = positions[j];
00120             }
00121         }
00122         // NOTE store best particle index?
00123     }
00124 
00125     // b)
00126     for( uint i = 0; i < deme->getSize(); i++ ) { // for each particle
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             //time variant weight, linear from weight to 0.4
00146             case TIME_VARIANT:
00147             weight_up = ( m_weight - 0.4 ) * ( m_maxIter - state->getGenerationNo() ) / m_maxIter + 0.4;
00148             break;
00149 
00150             // constant inertia weight
00151             case CONSTANT:
00152             default:
00153             weight_up = m_weight;
00154             break;
00155         }
00156         // calculate particle velocity according to the velocity equation (1)
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             // TODO apply position constriction
00170         }
00171 
00172         // determine new particle fitness
00173         evaluate( particle );
00174     }
00175 
00176     return true;
00177 }

Generated on Fri Jul 5 2013 09:34:22 for ECF by  doxygen 1.7.1