-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcmoea_example.cpp
264 lines (211 loc) · 8.59 KB
/
cmoea_example.cpp
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
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
// This example relies on the following other modules:
// - misc
// - nsgaext
// - cmoea
// Include standard
#include <iostream>
#include <fstream>
// Include sferes
#include <sferes/phen/parameters.hpp>
#include <sferes/gen/evo_float.hpp>
#include <sferes/eval/eval.hpp>
#include <sferes/stat/best_fit.hpp>
#include <sferes/eval/parallel.hpp>
#include <sferes/modif/dummy.hpp>
#include <sferes/modif/diversity.hpp>
#include <sferes/run.hpp>
#include <sferes/ea/dom_sort_basic.hpp>
// Include modules
#include <modules/cmoea/cmoea_util.hpp>
#include <modules/cmoea/cmoea_nsga2.hpp>
#include <modules/nsgaext/dom_sort_no_duplicates.hpp>
#include <modules/datatools/common_compare.hpp>
// Include local
#include <stat_cmoea.hpp>
/* NAMESPACES */
using namespace sferes;
using namespace sferes::gen::evo_float;
////////////////////////////////////////////////////////
////////////////////////////////////////////////////////
///////////* Parameters for the experiment *////////////
////////////////////////////////////////////////////////
////////////////////////////////////////////////////////
/* Parameters for Sferes */
struct Params {
// Parameters for the vector we are evolving
struct evo_float {
SFERES_CONST float cross_rate = 0.1f;
SFERES_CONST float mutation_rate = 0.1f;
SFERES_CONST float eta_m = 15.0f;
SFERES_CONST float eta_c = 10.0f;
SFERES_CONST mutation_t mutation_type = polynomial;
SFERES_CONST cross_over_t cross_over_type = sbx;
};
struct parameters {
SFERES_CONST float min = 0.0f;
SFERES_CONST float max = 1.0f;
};
struct cmoea_nsga {
// Type of non-dominated comparison that will be used by CMOEA NSGA
typedef sferes::ea::_dom_sort_basic::non_dominated_f non_dom_f;
};
struct cmoea {
// Size of every CMOEA bin
static const unsigned bin_size = 10;
// Number of CMOEA bins
static const unsigned nb_of_bins = 7; // = (2 ^ numberOfTasks - 1)
// Where fitness objective will be stored before non-dominated sorting
static const unsigned obj_index = 0;
};
/* Parameters for the population */
struct pop {
// Required by sferes, but ignored by CMOEA
SFERES_CONST unsigned size = 0;
// The number of individuals create to initialize the population
SFERES_CONST unsigned init_size = 10;
// The maximum number of individuals to try an create at the same time.
SFERES_CONST unsigned max_batch_size = 1024;
// The number of individuals created every generation
SFERES_CONST unsigned select_size = 100;
// The number of generations for which to run the algorithm
SFERES_CONST unsigned nb_gen = 200;
// // A multiplier on the number of individuals to create a generation 1.
// SFERES_CONST int initial_aleat = 1;
// Frequency at which to dump the archive
static const int dump_period = 200;
// // Fequency at which to write a checkpoint
// static const int checkpoint_period = 10;
};
struct ea {
typedef sferes::ea::dom_sort_basic_f dom_sort_f;
};
struct stats {
static const size_t period = 1;
};
};
////////////////////////////////////////////////////////
////////////////////////////////////////////////////////
////////////////* Fitness Function *////////////////////
////////////////////////////////////////////////////////
////////////////////////////////////////////////////////
/**
* Object to calculate the fitness of an individual over a set of randomly
* generated mazes.
*/
SFERES_FITNESS(ExampleCmoeaFit, sferes::fit::Fitness) {
public:
ExampleCmoeaFit(){
}
// Calculates behavioral distance between individuals
template<typename Indiv>
float dist(Indiv& ind) const {
return compare::l1diff(_behavior, ind.fit().getBehavior());
}
// Evaluates the performance of an individual on all tasks
template<typename Indiv>
void eval(Indiv& ind) {
for(size_t i=0; i<ind.size(); ++i){
_behavior.push_back(ind.data(i));
}
float hard = ind.data(0) * ind.data(1) * ind.data(2);
float easy = ind.data(3);
float task0 = 0;
float task1 = 0;
float task2 = 0;
if(easy > hard){
task0 = easy;
task1 = (1-hard)/2.0;
} else {
task0 = easy;
task1 = hard;
}
if(hard > 0.9){
task2 = ind.data(4);
}
_cmoea_task_performance.push_back(task0);
_cmoea_task_performance.push_back(task1);
_cmoea_task_performance.push_back(task2);
cmoea::calculate_bin_fitness_mult(_cmoea_task_performance, _cmoea_bin_fitness);
this->_objs.push_back(0);
this->_objs.push_back(0);
}
////////////////////////////////////////////////////////
////////////////////////////////////////////////////////
//////////////* Fitness attributes *////////////////////
////////////////////////////////////////////////////////
////////////////////////////////////////////////////////
template<class Archive>
void serialize(Archive & ar, const unsigned int version){
dbg::trace trace("fit", DBG_HERE);
sferes::fit::Fitness<Params,
typename stc::FindExact<ExampleCmoeaFit<Params, Exact>,
Exact>::ret>::serialize(ar, version);
ar & BOOST_SERIALIZATION_NVP(_behavior);
ar & BOOST_SERIALIZATION_NVP(_cmoea_task_performance);
ar & BOOST_SERIALIZATION_NVP(_cmoea_bin_fitness);
ar & BOOST_SERIALIZATION_NVP(_cmoea_bin_diversity);
ar & BOOST_SERIALIZATION_NVP(_divIndex);
}
// Getters and setters for CMOEA
std::vector<float> getBehavior() const { return _behavior;}
std::vector<float> &getBinFitnessVector(){return _cmoea_bin_fitness;}
float getBinFitness(size_t index){ return _cmoea_bin_fitness[index];}
std::vector<float> &getBinDiversityVector(){return _cmoea_bin_diversity;}
float getBinDiversity(size_t index){ return _cmoea_bin_diversity[index];}
float getCmoeaObj(size_t index){ return _cmoea_task_performance[index];}
void initBinDiversity(){
if(_cmoea_bin_diversity.size() != Params::cmoea::nb_of_bins){
_cmoea_bin_diversity.resize(Params::cmoea::nb_of_bins);
}
}
void setBinDiversity(size_t index, float div){
dbg::check_bounds(dbg::error, 0, index, _cmoea_bin_diversity.size(),
DBG_HERE);
_cmoea_bin_diversity[index] = div;
}
protected:
// Vector of robot (end) points over all mazes
std::vector<float> _behavior;
// Performance on each task, as required for cmoea
std::vector<float> _cmoea_task_performance;
// Performance on each combination of tasks, as required for cmoea
std::vector<float> _cmoea_bin_fitness;
// The diversity score of an individual, as calculated by cmoea
std::vector<float> _cmoea_bin_diversity;
// The index of the diversity objective in the objective array
int _divIndex;
};
////////////////////////////////////////////////////////
////////////////////////////////////////////////////////
//////////////////* Main Program *//////////////////////
////////////////////////////////////////////////////////
////////////////////////////////////////////////////////
/* Sets up and runs the experiment. */
int main(int argc, char **argv) {
std::cout << "Entering main: " << std::endl;
time_t t = time(0) + ::getpid();
std::cout<<"seed: " << t << std::endl;
srand(t);
/* Fitness function to use (a class, defined above), which makes use of the
* Params struct. */
typedef ExampleCmoeaFit<Params> fit_t;
// The genotype.
typedef gen::EvoFloat<5, Params> gen_t;
// The phenotype
typedef phen::Parameters<gen_t, fit_t, Params> phen_t;
//Behavioral distance based only on current population.
typedef modif::Diversity<> mod_t;
// What statistics should be gathered
typedef boost::fusion::vector<stat::StatCmoea<phen_t, Params> > stat_t;
// The evaluator for the network
typedef eval::Eval<Params> eval_t;
// CMOEA with NSGA-II non-dominated selection within each bin
typedef ea::CmoeaNsga2<phen_t, eval_t, stat_t, mod_t, Params> ea_t;
ea_t ea;
run_ea(argc, argv, ea);
/* Record completion (makes it easy to check if the job was preempted). */
std::cout << "\n==================================" << \
"\n====Evolutionary Run Complete!====" << \
"\n==================================\n";
return 0;
}