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

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

00001 #include "ECF_base.h"
00002 #include "ECF_macro.h"
00003 #include "AlgGenHookeJeeves.h"
00004 #include "SelFitnessProportionalOp.h"
00005 #include "SelRandomOp.h"
00006 #include "floatingpoint/FloatingPoint.h"
00007 
00008 
00009 GenHookeJeeves::GenHookeJeeves()
00010 {
00011     // define algorithm name (for referencing in config file)
00012     name_ = "GenHookeJeeves";
00013 
00014     // create selection operators needed
00015     selFitPropOp_ = static_cast<SelectionOperatorP> (new SelFitnessProportionalOp);
00016     selBestOp_    = static_cast<SelectionOperatorP> (new SelBestOp);
00017     selRandomOp_  = static_cast<SelectionOperatorP> (new SelRandomOp);
00018 }
00019 
00020 
00021 void GenHookeJeeves::registerParameters(StateP state)
00022 {
00023     // preciznost: minimalni delta_x
00024     registerParameter(state, "precision", (voidP) new double(0.000001), ECF::DOUBLE);
00025     // pocetni pomak (pocetni delta_x)
00026     registerParameter(state, "delta", (voidP) new double(1.), ECF::DOUBLE);
00027     // samo lokalna pretraga
00028     registerParameter(state, "localonly", (voidP) new uint(0), ECF::UINT);
00029 }
00030 
00031 
00032 bool GenHookeJeeves::initialize(StateP state)
00033 {
00034     // initialize all operators
00035     selFitPropOp_->initialize(state);
00036     selBestOp_->initialize(state);
00037     selRandomOp_->initialize(state);
00038 
00039     // read parameter values 
00040     voidP sptr = getParameterValue(state, "precision");
00041     precision_ = *((double*) sptr.get());
00042     sptr = getParameterValue(state, "delta");
00043     initialMove_ = *((double*) sptr.get());
00044     sptr = getParameterValue(state, "localonly");
00045     localOnly_ = *((uint*) sptr.get());
00046 
00047     // init pomake i zastavice postupka
00048     sptr = state->getRegistry()->getEntry("population.size");
00049     uint size = *((uint*) sptr.get());
00050     for(uint i = 0; i < size; i++) {
00051         delta_.push_back(initialMove_);
00052         changed_.push_back(true);
00053         converged_.push_back(false);
00054     }
00055 
00056     convergedTotal_ = 0;
00057 
00058     // ugly workaround za batch run, moramo jos vidjeti
00059     if(state->getGenotypes().size() > 1)
00060         return true;
00061 
00062     // procitaj parametre prvog genotipa i prepisi u novi genotip
00063     // (drugi genotip nam treba za operaciju pretrazivanja)
00064     // to sve moze i jednostavnije (npr. s privatnim vektorom genotipa), ali ovako mozemo koristiti i milestone!
00065     sptr = state->getGenotypes()[0]->getParameterValue(state, "dimension");
00066     uint numDimension = *((uint*) sptr.get());
00067     sptr = state->getGenotypes()[0]->getParameterValue(state, "lbound");
00068     double lbound = *((double*) sptr.get());
00069     sptr = state->getGenotypes()[0]->getParameterValue(state, "ubound");
00070     double ubound = *((double*) sptr.get());
00071 
00072     // stvori i dodaj novi genotip
00073     FloatingPointP fp (static_cast<FloatingPoint::FloatingPoint*> (state->getGenotypes()[0]->copy()));
00074     state->setGenotype(fp);
00075 
00076     // ako je lokalna pretraga, stvori i dodaj novi genotip za broj koraka do konvergencije svake jedinke
00077     if(localOnly_) {
00078         FloatingPointP fp2 (static_cast<FloatingPoint::FloatingPoint*> (state->getGenotypes()[0]->copy()));
00079         state->setGenotype(fp2);
00080         fp2->setParameterValue(state, "dimension", (voidP) new uint(1));
00081         fp2->setParameterValue(state, "lbound", (voidP) new double(0));
00082         fp2->setParameterValue(state, "ubound", (voidP) new double(1));
00083     }
00084 
00085     // postavi jednake parametre
00086     fp->setParameterValue(state, "dimension", (voidP) new uint(numDimension));
00087     fp->setParameterValue(state, "lbound", (voidP) new double(lbound));
00088     fp->setParameterValue(state, "ubound", (voidP) new double(ubound));
00089 
00090     return true;
00091 }
00092 
00093 
00094 bool GenHookeJeeves::advanceGeneration(StateP state, DemeP deme)
00095 {
00096     // fitnesi i pomocna jedinka za postupak pretrazivanja (koristimo Fitness objekte tako da radi i za min i max probleme)
00097     FitnessP neighbor[2];
00098     neighbor[0] = (FitnessP) (*deme)[0]->fitness->copy();
00099     neighbor[1] = (FitnessP) (*deme)[0]->fitness->copy();
00100     IndividualP temp (new Individual(state));
00101 
00102     uint mutacija = 0;
00103 
00104     // vrti isto za sve jedinke
00105     for(uint i = 0; i < deme->size(); i++) {
00106 
00107         if(localOnly_ && converged_[i])
00108             continue;
00109 
00110         IndividualP ind = deme->at(i);
00111         // bazna tocka:
00112         FloatingPointP x = boost::static_pointer_cast<FloatingPoint::FloatingPoint> (ind->getGenotype(0));
00113         // pocetna tocka pretrazivanja:
00114         FloatingPointP xn = boost::static_pointer_cast<FloatingPoint::FloatingPoint> (ind->getGenotype(1));
00115 
00116         FitnessP finalFit;
00117         // je li prva iteracija uz ovaj deltax?
00118         if(changed_[i]) {
00119             xn = (FloatingPointP) x->copy();
00120             changed_[i] = false;
00121             finalFit = (FitnessP) ind->fitness->copy();
00122         }
00123         // ako nije, trebamo evaluirati i pocetnu tocku pretrazivanja
00124         else {
00125             (*temp)[0] = xn;
00126             evaluate(temp);
00127             finalFit = temp->fitness;
00128         }
00129 
00130         // pretrazivanje
00131         for(uint dim = 0; dim < x->realValue.size(); dim++) {
00132             xn->realValue[dim] += delta_[i];    // pomak vektora
00133             (*temp)[0] = xn;                    // stavimo u pomocnu jedinku
00134             evaluate(temp);                     // evaluiramo jedinku
00135             neighbor[0] = temp->fitness;        // zabiljezimo fitnes
00136 
00137             // VARIJANTA A: originalni postupak za unimodalne fje
00138             // ako je drugi bolji, treceg niti ne gledamo
00139             if(neighbor[0]->isBetterThan(finalFit)) {
00140                 finalFit = neighbor[0];
00141                 continue;
00142             }
00143 
00144             xn->realValue[dim] -= 2 * delta_[i];
00145             (*temp)[0] = xn;
00146             evaluate(temp);
00147             neighbor[1] = temp->fitness;
00148 
00149             // je li treci bolji?
00150             if(neighbor[1]->isBetterThan(finalFit)) {
00151                 finalFit = neighbor[1];
00152                 continue;
00153             }
00154 
00155             // ako nije, vrati u sredinu
00156             xn->realValue[dim] += delta_[i];     // vrati u sredinu
00157             continue;
00158 
00159             // VARIJANTA B: gledamo sve tri tocke (za visemodalni slucaj)
00160             // odredi najbolju od 3
00161             if(finalFit->isBetterThan(neighbor[0]) && finalFit->isBetterThan(neighbor[1]))
00162                 ;
00163             else if(neighbor[0]->isBetterThan(neighbor[1])) {
00164                 xn->realValue[dim] += delta_[i];
00165                 finalFit = neighbor[0];
00166             }
00167             else {
00168                 xn->realValue[dim] -= delta_[i];
00169                 finalFit = neighbor[1];
00170             }
00171         }
00172 
00173         // je li tocka nakon pretrazivanja bolja od bazne tocke?
00174         if(finalFit->isBetterThan(ind->fitness)) {
00175             FloatingPointP xnc (xn->copy());
00176             // preslikavanje:
00177             for(uint dim = 0; dim < x->realValue.size(); dim++)
00178                 xn->realValue[dim] = 2 * xn->realValue[dim] - x->realValue[dim];
00179             x = xnc;                  // nova bazna tocka
00180             ind->fitness = finalFit;  // ne zaboravimo i novi fitnes
00181         }
00182         // nije, smanji deltax i resetiraj tocku pretrazivanja
00183         else {
00184             delta_[i] /= 2;
00185             xn = (FloatingPointP) x->copy();
00186             changed_[i] = true;
00187         }
00188 
00189         // azuriraj genotipe (pointeri u jedinki):
00190         (*ind)[0] = x;
00191         (*ind)[1] = xn;
00192 
00193 
00194         // dio koji obradjuje samo Hooke-Jeeves (localonly)
00195         if(localOnly_) {
00196             if(converged_[i] == false && changed_[i] == true && delta_[i] < precision_) {
00197                 converged_[i] = true;
00198                 convergedTotal_++;
00199 
00200                 // zapisi generaciju u kojoj je jedinka konvergirala
00201                 FloatingPointP fp = boost::static_pointer_cast<FloatingPoint::FloatingPoint> (ind->getGenotype(2));
00202                 fp->realValue[0] = state->getGenerationNo();
00203             }
00204 
00205 
00206             if(convergedTotal_ == converged_.size()) {
00207                 state->setTerminateCond();
00208                 std::cout << "svi konvergirali!" << std::endl;
00209             }
00210 
00211             continue;   // sljedeca jedinka
00212 
00213         }
00214 
00215         // ako je jedinka konvergirala (i ako nije trenutno najbolja), stvori novu krizanjem + mutacijom
00216         if(changed_[i] == true && delta_[i] < precision_ && (selBestOp_->select(*deme) != ind)) {
00217             IndividualP first, second;
00218             first = second = selFitPropOp_->select(*deme);
00219             while(second == first)
00220                 second = selFitPropOp_->select(*deme);
00221 
00222             // VARIJANTA C: slucajni odabir roditelja (umjesto fitness proportional)
00223 //          first = second = selRandomOp_->select(*deme);
00224 //          while(second == first)
00225 //              second = selRandomOp_->select(*deme);
00226 
00227             // krizanje, mutacija, evaluacija
00228             mate(first, second, ind);
00229             mutate(ind);
00230             evaluate(ind);
00231             delta_[i] = initialMove_;   // ponovo pocetni pomak
00232         }
00233 
00234     }
00235 
00236     return true;
00237 }

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