Repository navigation
Expand file tree
/
Copy pathopoea.hpp
More file actions
165 lines (150 loc) · 6.79 KB
/
Copy pathopoea.hpp
File metadata and controls
165 lines (150 loc) · 6.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
/**
* Here we implement the (1+1)-EA>0, is a slight extension of
* the off-the-shelf evolutionary algorithm with one parent
* (mu=1) that generates one single offspring solution in each
* step (lambda=1) by flipping each bit of the parent solution
* with the same probability of 1/n.
* The difference of the (1+1)-EA<0 and the (1+1)-EA is that
* in the (1+1)-EA<0 [implemented here], it is ensured that
* always at least one bit is flipped.
*
* Author: Thomas Weise
* Institute of Applied Optimization
* Hefei University
* Hefei, Anhui, China
* Email: [email protected], [email protected]
*/
#ifndef _OPOEA_H_
#define _OPOEA_H_
#include "utils/common.hpp"
namespace modularGA
{
namespace fea
{
// void run_ea1p1(const string folder_path,
// shared_ptr<IOHprofiler_suite<int>> suite,
// const unsigned long long eval_budget,
// const unsigned long long independent_runs,
// const unsigned long long rand_seed);
/**
* Here we implement the (1+1)-EA>0, is a slight extension of
* the off-the-shelf evolutionary algorithm with one parent
* (mu=1) that generates one single offspring solution in each
* step (lambda=1) by flipping each bit of the parent solution
* with the same probability of 1/n.
* The difference of the (1+1)-EA<0 and the (1+1)-EA is that
* in the (1+1)-EA<0 [implemented here], it is ensured that
* always at least one bit is flipped.
*
* Author: Thomas Weise
* Institute of Applied Optimization
* Hefei University
* Hefei, Anhui, China
* Email: [email protected], [email protected]
*/
void ea1p1(shared_ptr<ioh::problem::Integer> problem,
shared_ptr<ioh::logger::Analyzer> logger,
const unsigned long long eval_budget)
{
// check input variables
if (eval_budget <= 1)
throw "eval_budget must be > 1";
if (!problem)
throw "problem must not be null";
if (!logger)
throw "logger must not be null";
// n be the number of variables
const int n = problem->meta_data().n_variables;
if (n <= 0)
throw "number of variables must be positive";
// the bit flip probability
const double p = 1.0 / ((double)n);
if ((!isfinite(p)) || (p <= 0.0) || (p >= 1.0))
throw "p must be from (0,1)";
// xcur is the current best candidate solution (based on frequency fitness)
std::vector<int> xcur;
// xnew is the new candidate solution generated in each step
std::vector<int> xnew;
// ycur is the objective value of the current solution
double ycur = std::numeric_limits<double>::infinity();
// ynew is the objective value of the new solution
double ynew = std::numeric_limits<double>::infinity();
// first we generate the random initial solution
xcur.reserve(n);
for (int i = 0; i < n; i++)
{
xcur.push_back((int)(2 * uniform_random()));
}
// we evaluate the random initial solution
ycur = (*problem)(xcur);
// we perform iterations until either the optimum is discovered or the budget has been exhausted
int count = eval_budget;
unsigned long long int step = 1;
while (((++step) <= eval_budget) && (!problem->state().optimum_found))
{
// copy the current solution to the new solution
xnew = xcur;
bool unchanged = true;
// until the solution changes, repeat
do
{
// flip each bit with the independent probability of 1/n
for (int i = n; (--i) >= 0;)
{
if (uniform_random() < p)
{
unchanged = false; // there was a change
xnew[i] ^= 1; // flip the bit
}
}
} while (unchanged); // repeat until at least one change
// evaluate the new candidate solution
ynew = (*problem)(xnew);
// if new solution is at least as good as current one, accept it
if (ynew >= ycur)
{
ycur = ynew;
xcur = xnew;
}
}
}
// run the (1+1) ea
void run_ea1p1(const string folder_path,
shared_ptr<ioh::suite::Suite<ioh::problem::Integer> > suite,
const unsigned long long eval_budget,
const unsigned long long independent_runs,
const unsigned long long rand_seed)
{
if (folder_path.empty())
throw "folder path cannot be empty";
if (!suite)
throw "suite cannot be null";
if (eval_budget <= 1)
throw "eval_budget must be > 1";
if (independent_runs < 1)
throw "independent_runs must be > 0";
const string algorithm_name = "opoea";
std::shared_ptr<ioh::logger::Analyzer> logger(
new ioh::logger::Analyzer({ioh::trigger::on_improvement}, // trigger when the objective value improves
{}, // no additional properties
folder_path, // path to store data
algorithm_name, // name of the folder in path, which will be newly created
algorithm_name, // name of the algoritm
algorithm_name, // additional info about the algorithm
false // where to store x positions in the data files
));
random_gen.seed(rand_seed);
shared_ptr<ioh::problem::Integer> problem;
for (auto &problem: *suite)
{
problem->attach_logger(*logger);
for (unsigned long long i = 0; i < independent_runs; i++)
{
ea1p1(problem, logger, eval_budget);
problem->reset();
}
}
}
}
}
#endif