• 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     areGenotypesAdded_ = false;
00010 
00011     // create selection operators needed
00012     // in this case, SelBestOp
00013     selBestOp = static_cast<SelectionOperatorP> (new SelBestOp);
00014 }
00015 
00016 
00017 // register algorithm parameters
00018 void ParticleSwarmOptimization::registerParameters(StateP state)
00019 {
00020     registerParameter(state, "weightType", (voidP) new InertiaWeightType(CONSTANT), ECF::INT,
00021         "weight type update: 0 - constant, 1 - time dependant (based on max generations)");
00022     registerParameter(state, "weight", (voidP) new double(0.8), ECF::DOUBLE,
00023         "initial inertia weight (either constant or time dependant)");
00024     registerParameter(state, "maxVelocity", (voidP) new double(10.0), ECF::DOUBLE,
00025         "max particle velocity");
00026     registerParameter(state, "bounded", (voidP) new uint(0), ECF::UINT, 
00027         "should the algorithm respect the bounds defined in the genotype or not (default: 0)");
00028 }
00029 
00030 
00031 bool ParticleSwarmOptimization::initialize(StateP state)
00032 {
00033     // initialize all operators
00034     selBestOp->initialize(state);
00035 
00036     voidP weightType = getParameterValue(state, "weightType");
00037     m_weightType = *((InertiaWeightType*) weightType.get());
00038 
00039     voidP weight = getParameterValue(state, "weight");
00040     m_weight = *((double*) weight.get());
00041 
00042     voidP maxV = getParameterValue(state, "maxVelocity");
00043     m_maxV = *((double*) maxV.get());
00044 
00045     // test if inertia weight type is time variant and if so, check if max iterations specified
00046     if(m_weightType == TIME_VARIANT) {
00047         if(state->getRegistry()->isModified("term.maxgen")) {
00048             // read maxgen parameter
00049             m_maxIter = *(boost::static_pointer_cast<int>( state->getRegistry()->getEntry("term.maxgen") ));
00050         }
00051         else {
00052             ECF_LOG_ERROR(state, "Error: term.maxgen has to be specified in order to use time variant inertia eight in PSO algorithm");
00053             throw("");
00054         }
00055     }
00056 
00057     // algorithm accepts a single FloatingPoint Genotype
00058     FloatingPointP flp (new FloatingPoint::FloatingPoint);
00059     if(state->getGenotypes()[0]->getName() != flp->getName()) {
00060         ECF_LOG_ERROR(state, "Error: PSO algorithm accepts only a single FloatingPoint genotype!");
00061         throw ("");
00062     }
00063 
00064     voidP sptr = state->getGenotypes()[0]->getParameterValue(state, "dimension");
00065     uint numDimension = *((uint*) sptr.get());
00066 
00067     voidP bounded = getParameterValue(state, "bounded");
00068     bounded_ = *((bool*) bounded.get());
00069 
00070     sptr = state->getGenotypes()[0]->getParameterValue(state, "lbound");
00071     lbound_ = *((double*) sptr.get());
00072 
00073     sptr = state->getGenotypes()[0]->getParameterValue(state, "ubound");
00074     ubound_ = *((double*) sptr.get());
00075 
00076     // batch run check
00077     if(areGenotypesAdded_)
00078         return true;
00079 
00080     FloatingPointP flpoint[4];
00081     for(uint iGen = 1; iGen < 4; iGen++) {
00082 
00083         flpoint[iGen] = (FloatingPointP) new FloatingPoint::FloatingPoint;
00084         state->setGenotype(flpoint[iGen]);
00085 
00086         if(iGen == 3)
00087             flpoint[iGen]->setParameterValue(state, "dimension", (voidP) new uint(1));
00088         else
00089             flpoint[iGen]->setParameterValue(state, "dimension", (voidP) new uint(numDimension));
00090 
00091         // other parameters are proprietary (ignored by the algorithm)
00092         flpoint[iGen]->setParameterValue(state, "lbound", (voidP) new double(0));
00093         flpoint[iGen]->setParameterValue(state, "ubound", (voidP) new double(1));
00094     }
00095     ECF_LOG(state, 1, "PSO algorithm: added 3 FloatingPoint genotypes (particle velocity, best-so-far postition, best-so-far fitness value)");
00096 
00097     // mark adding of genotypes
00098     areGenotypesAdded_ = true;
00099 
00100     return true;
00101 }
00102 
00103 
00104 bool ParticleSwarmOptimization::advanceGeneration(StateP state, DemeP deme)
00105 {
00106 //       a) For each particle:
00107 //          1) If the fitness value is better than the best fitness value (pBest) in  history
00108 //          2) Set current value as the new pBest
00109 //          End
00110 //       b) For each particle:
00111 //          1) Find, in the particle neighborhood, the particle with the best fitness
00112 //          2) Calculate particle velocity according to the velocity equation (1)
00113 //          3) Apply the velocity constriction
00114 //          4) Update particle position according to the position equation (2)
00115 //          5) Apply the position constriction
00116 //          6) Calculate fitness value
00117 //          End
00118 
00119     // a)
00120     for( uint i = 0; i < deme->getSize(); i++ ) { // for each particle 
00121         IndividualP particle = deme->at(i);
00122 
00123         // the whole point of this section is to compare fitness and pbest
00124         FloatingPointP flp = boost::dynamic_pointer_cast<FloatingPoint::FloatingPoint> (particle->getGenotype(3));
00125         double &particlePbestFitness = flp->realValue[0];
00126         double fitness = particle->fitness->getValue();
00127 
00128         flp = boost::dynamic_pointer_cast<FloatingPoint::FloatingPoint> (particle->getGenotype(0));
00129         std::vector< double > &positions = flp->realValue;
00130 
00131         flp = boost::dynamic_pointer_cast<FloatingPoint::FloatingPoint> (particle->getGenotype(2));
00132         std::vector< double > &pbestx = flp->realValue;
00133 
00134         // set particle pbestx-es
00135         if( /*iter == 0 ||*/ fitness < particlePbestFitness ) { // minimize error
00136             particlePbestFitness = fitness;
00137 
00138             // set pbestx-es
00139             for( uint j = 0;j<pbestx.size();j++ ) {
00140                 pbestx[j] = positions[j];
00141             }
00142         }
00143         // NOTE store best particle index?
00144     }
00145 
00146     // b)
00147     for( uint i = 0; i < deme->getSize(); i++ ) { // for each particle
00148         IndividualP particle = deme->at(i);
00149 
00150         IndividualP bestParticle = selBestOp->select( *deme );
00151 
00152         FloatingPointP flp = boost::dynamic_pointer_cast<FloatingPoint::FloatingPoint> (particle->getGenotype(0));
00153         std::vector< double > &positions = flp->realValue;
00154 
00155         flp = boost::dynamic_pointer_cast<FloatingPoint::FloatingPoint> (particle->getGenotype(1));
00156         std::vector< double > &velocities = flp->realValue;
00157 
00158         flp = boost::dynamic_pointer_cast<FloatingPoint::FloatingPoint> (particle->getGenotype(2));
00159         std::vector< double > &pbestx = flp->realValue;
00160 
00161 
00162         double weight_up;
00163 
00164         switch( m_weightType )
00165         {
00166             //time variant weight, linear from weight to 0.4
00167             case TIME_VARIANT:
00168             weight_up = ( m_weight - 0.4 ) * ( m_maxIter - state->getGenerationNo() ) / m_maxIter + 0.4;
00169             break;
00170 
00171             // constant inertia weight
00172             case CONSTANT:
00173             default:
00174             weight_up = m_weight;
00175             break;
00176         }
00177         // calculate particle velocity according to the velocity equation (1)
00178         flp = boost::dynamic_pointer_cast<FloatingPoint::FloatingPoint> (bestParticle->getGenotype(2));
00179         std::vector< double > &bestParticlesPbestx = flp->realValue;
00180         for( uint j = 0; j < velocities.size(); j++ ) {
00181             double velocity;
00182 
00183             velocity = weight_up * velocities[j] +
00184                2 * (rand()/(float)RAND_MAX) * (pbestx[j] - positions[j]) +
00185                2 * (rand()/(float)RAND_MAX) * (bestParticlesPbestx[j] - positions[j]);
00186             if( velocity > m_maxV ) velocity = m_maxV;
00187             velocities[j] = velocity;
00188 
00189             positions[j] += velocities[j];
00190             // TODO apply position constriction
00191 
00192             // check for bounds
00193             if(bounded_) {
00194                 if(positions[j] < lbound_)
00195                     positions[j] = lbound_;
00196                 if(positions[j] > ubound_)
00197                     positions[j] = ubound_;
00198             }
00199         }
00200 
00201         // determine new particle fitness
00202         evaluate( particle );
00203     }
00204 
00205     return true;
00206 }

Generated on Tue Nov 4 2014 13:04:30 for ECF by  doxygen 1.7.1