• 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     // postavi jednake parametre
00077     fp->setParameterValue(state, "dimension", (voidP) new uint(numDimension));
00078     fp->setParameterValue(state, "lbound", (voidP) new double(lbound));
00079     fp->setParameterValue(state, "ubound", (voidP) new double(ubound));
00080 
00081     return true;
00082 }
00083 
00084 
00085 bool GenHookeJeeves::advanceGeneration(StateP state, DemeP deme)
00086 {
00087     // fitnesi i pomocna jedinka za postupak pretrazivanja (koristimo Fitness objekte tako da radi i za min i max probleme)
00088     FitnessP neighbor[2];
00089     neighbor[0] = (FitnessP) (*deme)[0]->fitness->copy();
00090     neighbor[1] = (FitnessP) (*deme)[0]->fitness->copy();
00091     IndividualP temp (new Individual(state));
00092 
00093     uint mutacija = 0;
00094 
00095     // vrti isto za sve jedinke
00096     for(uint i = 0; i < deme->size(); i++) {
00097 
00098         if(localOnly_ && converged_[i])
00099             continue;
00100 
00101         IndividualP ind = deme->at(i);
00102         // bazna tocka:
00103         FloatingPointP x = boost::static_pointer_cast<FloatingPoint::FloatingPoint> (ind->getGenotype(0));
00104         // pocetna tocka pretrazivanja:
00105         FloatingPointP xn = boost::static_pointer_cast<FloatingPoint::FloatingPoint> (ind->getGenotype(1));
00106 
00107         FitnessP finalFit;
00108         // je li prva iteracija uz ovaj deltax?
00109         if(changed_[i]) {
00110             xn = (FloatingPointP) x->copy();
00111             changed_[i] = false;
00112             finalFit = (FitnessP) ind->fitness->copy();
00113         }
00114         // ako nije, trebamo evaluirati i pocetnu tocku pretrazivanja
00115         else {
00116             (*temp)[0] = xn;
00117             evaluate(temp);
00118             finalFit = temp->fitness;
00119         }
00120 
00121         // pretrazivanje
00122         for(uint dim = 0; dim < x->realValue.size(); dim++) {
00123             xn->realValue[dim] += delta_[i];    // pomak vektora
00124             (*temp)[0] = xn;                    // stavimo u pomocnu jedinku
00125             evaluate(temp);                     // evaluiramo jedinku
00126             neighbor[0] = temp->fitness;        // zabiljezimo fitnes
00127 
00128             // VARIJANTA A: originalni postupak za unimodalne fje
00129             // ako je drugi bolji, treceg niti ne gledamo
00130             if(neighbor[0]->isBetterThan(finalFit)) {
00131                 finalFit = neighbor[0];
00132                 continue;
00133             }
00134 
00135             xn->realValue[dim] -= 2 * delta_[i];
00136             (*temp)[0] = xn;
00137             evaluate(temp);
00138             neighbor[1] = temp->fitness;
00139 
00140             // je li treci bolji?
00141             if(neighbor[1]->isBetterThan(finalFit)) {
00142                 finalFit = neighbor[1];
00143                 continue;
00144             }
00145 
00146             // ako nije, vrati u sredinu
00147             xn->realValue[dim] += delta_[i];     // vrati u sredinu
00148             continue;
00149 
00150             // VARIJANTA B: gledamo sve tri tocke (za visemodalni slucaj)
00151             // odredi najbolju od 3
00152             if(finalFit->isBetterThan(neighbor[0]) && finalFit->isBetterThan(neighbor[1]))
00153                 ;
00154             else if(neighbor[0]->isBetterThan(neighbor[1])) {
00155                 xn->realValue[dim] += delta_[i];
00156                 finalFit = neighbor[0];
00157             }
00158             else {
00159                 xn->realValue[dim] -= delta_[i];
00160                 finalFit = neighbor[1];
00161             }
00162         }
00163 
00164         // je li tocka nakon pretrazivanja bolja od bazne tocke?
00165         if(finalFit->isBetterThan(ind->fitness)) {
00166             FloatingPointP xnc (xn->copy());
00167             // preslikavanje:
00168             for(uint dim = 0; dim < x->realValue.size(); dim++)
00169                 xn->realValue[dim] = 2 * xn->realValue[dim] - x->realValue[dim];
00170             x = xnc;                  // nova bazna tocka
00171             ind->fitness = finalFit;  // ne zaboravimo i novi fitnes
00172         }
00173         // nije, smanji deltax i resetiraj tocku pretrazivanja
00174         else {
00175             delta_[i] /= 2;
00176             xn = (FloatingPointP) x->copy();
00177             changed_[i] = true;
00178         }
00179 
00180         // azuriraj genotipe (pointeri u jedinki):
00181         (*ind)[0] = x;
00182         (*ind)[1] = xn;
00183 
00184 
00185         // dio koji obradjuje samo Hooke-Jeeves (localonly)
00186         if(localOnly_) {
00187             if(converged_[i] == false && changed_[i] == true && delta_[i] < precision_) {
00188                 converged_[i] = true;
00189                 convergedTotal_++;
00190             }
00191 
00192             if(convergedTotal_ == converged_.size()) {
00193                 state->setTerminateCond();
00194                 //std::cout << "svi konvergirali!" << std::endl;
00195             }
00196 
00197             continue;   // sljedeca jedinka
00198 
00199         }
00200 
00201         // ako je jedinka konvergirala (i ako nije trenutno najbolja), stvori novu krizanjem + mutacijom
00202         if(changed_[i] == true && delta_[i] < precision_ && (selBestOp_->select(*deme) != ind)) {
00203             IndividualP first, second;
00204             first = second = selFitPropOp_->select(*deme);
00205             while(second == first)
00206                 second = selFitPropOp_->select(*deme);
00207 
00208             // VARIJANTA C: slucajni odabir roditelja (umjesto fitness proportional)
00209 //          first = second = selRandomOp_->select(*deme);
00210 //          while(second == first)
00211 //              second = selRandomOp_->select(*deme);
00212 
00213             // krizanje, mutacija, evaluacija
00214             mate(first, second, ind);
00215             mutate(ind);
00216             evaluate(ind);
00217             delta_[i] = initialMove_;   // ponovo pocetni pomak
00218         }
00219 
00220     }
00221 
00222     return true;
00223 }

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