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