• Main Page
  • Classes
  • Files
  • File List

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

00001 #include "AlgParticleSwarmOptimization.h"
00002 
00003 ParticleSwarmOptimization::ParticleSwarmOptimization()
00004 {
00005     // define algorithm name
00006     name_ = "ParticleSwarmOptimization";
00007 
00008     // create selection operators needed
00009     // in this case, SelBestOp
00010     selBestOp = static_cast<SelectionOperatorP> (new SelBestOp);
00011 }
00012 
00013 
00014 // register algorithm parameters
00015 void ParticleSwarmOptimization::registerParameters(StateP state)
00016 {
00017     registerParameter(state, "weightType", (voidP) new InertiaWeightType(CONSTANT), ECF::INT);
00018     registerParameter(state, "weight", (voidP) new double(0.8), ECF::DOUBLE);
00019     registerParameter(state, "maxVelocity", (voidP) new double(10.0), ECF::DOUBLE);
00020     registerParameter(state, "particleCount", (voidP) new uint(10), ECF::INT);
00021 }
00022 
00023 
00024 bool ParticleSwarmOptimization::initialize(StateP state)
00025 {
00026     // initialize all operators
00027     selBestOp->initialize(state);
00028 
00029     voidP weightType = getParameterValue(state, "weightType");
00030     m_weightType = *((InertiaWeightType*) weightType.get());
00031 
00032     voidP weight = getParameterValue(state, "weight");
00033     m_weight = *((double*) weight.get());
00034 
00035     voidP maxV = getParameterValue(state, "maxVelocity");
00036     m_maxV = *((double*) maxV.get());
00037 
00038     // test if inertia weight type is time variant and if so, check if max iterations specified
00039     if(m_weightType == TIME_VARIANT) {
00040         if(state->getRegistry()->isModified("term.maxgen")) {
00041             // read maxgen parameter
00042             m_maxIter = *(boost::static_pointer_cast<int>( state->getRegistry()->getEntry("term.maxgen") ));
00043         }
00044         else {
00045             state->getLogger()->log(1, "Error: term.maxgen has to be specified in order to use time variant inertia eight in PSO algorithm");
00046             throw("");
00047         }
00048     }
00049 
00050     // algorithm accepts a single Binary Genotype (for now)
00051     BinaryP bin = (BinaryP) new Binary::Binary;
00052     if(state->getGenotypes()[0]->getName() != bin->getName()
00053         || state->getGenotypes().size() != 1) {
00054         state->getLogger()->log(1, "Error: PSO algorithm accepts only a single Binary genotype!");
00055         throw ("");
00056     }
00057 
00058     voidP sptr = state->getGenotypes()[0]->getParameterValue(state, "dimension");
00059     uint numDimension = *((uint*) sptr.get());
00060 
00061     BinaryP binary[4];
00062     for(uint iGen = 1; iGen < 4; iGen++) {
00063 
00064         binary[iGen] = (BinaryP) new Binary::Binary;
00065         state->setGenotype(binary[iGen]);
00066 
00067         if(iGen == 3)
00068             binary[iGen]->setParameterValue(state, "dimension", (voidP) new uint(1));
00069         else
00070             binary[iGen]->setParameterValue(state, "dimension", (voidP) new uint(numDimension));
00071 
00072         // other parameters are proprietary (ignored by the algorithm)
00073         binary[iGen]->setParameterValue(state, "lbound", (voidP) new double(0));
00074         binary[iGen]->setParameterValue(state, "ubound", (voidP) new double(1));
00075         binary[iGen]->setParameterValue(state, "precision", (voidP) new uint(1));
00076     }
00077     state->getLogger()->log(1, "PSO algorithm: added 3 Binary 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         BinaryP bin = boost::dynamic_pointer_cast<Binary::Binary> (particle->getGenotype(3));
00104         double &particlePbestFitness = bin->realValue[0];
00105         double fitness = particle->fitness->getValue();
00106 
00107         bin = boost::dynamic_pointer_cast<Binary::Binary> (particle->getGenotype(0));
00108         std::vector< double > &positions = bin->realValue;
00109 
00110         bin = boost::dynamic_pointer_cast<Binary::Binary> (particle->getGenotype(2));
00111         std::vector< double > &pbestx = bin->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         BinaryP bin = boost::dynamic_pointer_cast<Binary::Binary> (particle->getGenotype(0));
00132         std::vector< double > &positions = bin->realValue;
00133 
00134         bin = boost::dynamic_pointer_cast<Binary::Binary> (particle->getGenotype(1));
00135         std::vector< double > &velocities = bin->realValue;
00136 
00137         bin = boost::dynamic_pointer_cast<Binary::Binary> (particle->getGenotype(2));
00138         std::vector< double > &pbestx = bin->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         bin = boost::dynamic_pointer_cast<Binary::Binary> (bestParticle->getGenotype(2));
00158         std::vector< double > &bestParticlesPbestx = bin->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 Wed Sep 1 2010 14:31:21 for ECF by  doxygen 1.7.1