ECF 1.5
AlgCuckooSearch.cpp
1#include "ECF_base.h"
2#include "floatingpoint/FloatingPoint.h"
3#include "AlgCuckooSearch.h"
4#include <boost/random/normal_distribution.hpp>
5#include <boost/random.hpp>
6#include <ctime>
7#include <cstdlib>
8#include <vector>
9
10
11CuckooSearch::CuckooSearch()
12{
13 name_ = "CuckooSearch";
14 selBestOp = static_cast<SelectionOperatorP> (new SelBestOp);
15}
16
17
19{
20 registerParameter(state, "pa", (voidP) new double(0.75), ECF::DOUBLE);
21}
22
23
24bool CuckooSearch::initialize(StateP state)
25{
26 selBestOp->initialize(state);
27
28 voidP pDiscovery = getParameterValue(state, "pa");
29 pa = *((double*)pDiscovery.get());
30 if (pa < 0 || pa > 1)
31 {
32 ECF_LOG_ERROR(state, "Error - pa must be in interval [0,1]");
33 throw "";
34 }
35
36 // reading boudaries and problem dimension
37 voidP lBound = state->getGenotypes()[0]->getParameterValue(state, "lbound");
38 lbound = *((double*)lBound.get());
39 voidP uBound = state->getGenotypes()[0]->getParameterValue(state, "ubound");
40 ubound = *((double*)uBound.get());
41 voidP sptr = state->getGenotypes()[0]->getParameterValue(state, "dimension");
42 numDimension = *((uint*)sptr.get());
43
44 // algorithm accepts a single FloatingPoint or Binary genotype
45 // or a genotype derived from the abstract RealValueGenotype class
46 GenotypeP activeGenotype = state->getGenotypes()[0];
47 RealValueGenotypeP rv = boost::dynamic_pointer_cast<RealValueGenotype> (activeGenotype);
48 if(!rv) {
49 ECF_LOG_ERROR(state, "Error: Cuckoo Search algorithm accepts only a RealValueGenotype derived genotype! (FloatingPoint or Binary)");
50 throw ("");
51 }
52
53 return true;
54}
55
56
57bool CuckooSearch::advanceGeneration(StateP state, DemeP deme)
58{
59 double sigma = 0.696574502;
60 boost::mt19937 rng;
61 boost::normal_distribution<> nd(0.0, 1.0);
62 boost::variate_generator<boost::mt19937&,
63 boost::normal_distribution<> > var_nor(rng, nd);
64
65 IndividualP best = selBestOp->select(*deme);
66 FloatingPointP bestFp = boost::static_pointer_cast<FloatingPoint::FloatingPoint> (best->getGenotype(0));
67
68 // cuckoos via Levy flights (by Mantegna's algorithm)
69 // new individual is added to population only if it is better than original individual
70 for (uint i = 0; i < deme->size(); i++) {
71 IndividualP trial = (IndividualP)deme->at(i)->copy();
72 FloatingPointP trialFp = boost::static_pointer_cast<FloatingPoint::FloatingPoint> (trial->getGenotype(0));
73 for (uint j = 0; j < numDimension; j++) {
74 double u = var_nor() * sigma;
75 double v = var_nor();
76 double step = u / pow(fabs(v), 2 / (double)3);
77 double randn = var_nor();
78 double diff = trialFp->realValue[j] - bestFp->realValue[j];
79 double stepsize = 0.01 * step * diff;
80 trialFp->realValue[j] = trialFp->realValue[j] + stepsize*randn;
81 if (trialFp->realValue[j] > ubound)
82 trialFp->realValue[j] = ubound;
83 if (trialFp->realValue[j] < lbound)
84 trialFp->realValue[j] = lbound;
85 }
86 evaluate(trial);
87 if (trial->fitness->isBetterThan(deme->at(i)->fitness))
88 replaceWith(deme->at(i), trial);
89 }
90
91 // copy all individuals
92 std::vector<IndividualP> nest1;
93 std::vector<IndividualP> nest2;
94 for (uint i = 0; i < deme->size(); i++) {
95 IndividualP indCp = (IndividualP)deme->at(i)->copy();
96 nest1.push_back(indCp);
97 nest2.push_back(indCp);
98 }
99
100 // replace some individuals/nests by constructing new nests
101 // nest is replaced only if it is better than original
102 random_shuffle(nest1.begin(), nest1.end());
103 random_shuffle(nest2.begin(), nest2.end());
104 double randNum = (double)rand() / RAND_MAX;
105 for (uint i = 0; i < deme->size(); i++) {
106 IndividualP trial = (IndividualP)deme->at(i)->copy();
107 FloatingPointP trialFp1 = boost::static_pointer_cast<FloatingPoint::FloatingPoint> (nest1.at(i)->getGenotype(0));
108 FloatingPointP trialFp2 = boost::static_pointer_cast<FloatingPoint::FloatingPoint> (nest2.at(i)->getGenotype(0));
109 FloatingPointP trialFp = boost::static_pointer_cast<FloatingPoint::FloatingPoint> (trial->getGenotype(0));
110
111 for (uint j = 0; j < numDimension; j++) {
112 if ((double)rand() / RAND_MAX < pa) {
113 double stepsize = (trialFp1->realValue[j] - trialFp2->realValue[j])*randNum;
114 trialFp->realValue[j] += stepsize;
115 if (trialFp->realValue[j] > ubound)
116 trialFp->realValue[j] = ubound;
117 if (trialFp->realValue[j] < lbound)
118 trialFp->realValue[j] = lbound;
119 }
120 }
121
122 evaluate(trial);
123 if (trial->fitness->isBetterThan(deme->at(i)->fitness))
124 replaceWith(deme->at(i), trial);
125 }
126 return true;
127
128}
129
std::string name_
algorithm name
Definition: Algorithm.h:23
bool registerParameter(StateP state, std::string name, voidP value, enum ECF::type T, std::string description="")
Helper function: register a single parameter with the system.
Definition: Algorithm.h:35
voidP getParameterValue(StateP state, std::string name)
Helper function: get parameter value from the system.
Definition: Algorithm.h:46
void replaceWith(IndividualP oldInd, IndividualP newInd)
Helper function: replace an individual in current deme.
Definition: Algorithm.h:187
void evaluate(IndividualP ind)
Helper function: evaluate an individual.
Definition: Algorithm.h:157
double pa
percentage of solutions which will be replaced (similar to mutation probability)
void registerParameters(StateP state)
Register algorithm's parameters (if any).
bool initialize(StateP state)
Initialize the algorithm, read parameters from the system, do a sanity check.
bool advanceGeneration(StateP state, DemeP deme)
Perform a single generation on a single deme.
Best individual selection operator.
Definition: SelBestOp.h:10