Brush C++ API
A flexible interpretable machine learning framework
Loading...
Searching...
No Matches
archive.cpp
Go to the documentation of this file.
1#include "archive.h"
2
3namespace Brush {
4namespace Pop {
5
6template<ProgramType T>
8
9template<ProgramType T>
10void Archive<T>::set_objectives(vector<string> objectives)
11{
12 this->sort_complexity = in(objectives, std::string("complexity"))
13 || in(objectives, std::string("linear_complexity"));
14
15 this->linear_complexity = in(objectives, std::string("linear_complexity"));
16}
17
18// sorting etc --- all done using fitness class (easier to compare regardless of obj func)
19template<ProgramType T>
21 const Individual<T>& rhs)
22{
23 // TODO: use getters for all info in fitness (instead of directly accessing them?).
24 // other option would be having the getters and setters to use iin pybind11, but
25 // in cpp we do it directly (we know how to manipulate this thing, but users may not,
26 // so these setters could do some validation to justify its existence).
27 return lhs.fitness.complexity < rhs.fitness.complexity;
28}
29
30template<ProgramType T>
36
37template<ProgramType T>
39 const Individual<T>& rhs)
40{
41 // sort based on index (we can have more than 2 obj in brush implementation)
42 // obs: because of the weights, every objective is a maximization problem
43 // when comparing weighted values (which should be the right way of doing it)
44 // the bigger the better. the weights allow us to use different min/max metrics
45 // without having to deal with this particular details
46
47 float lhs_obj1 = lhs.fitness.wvalues.at(0);
48 float rhs_obj1 = rhs.fitness.wvalues.at(0);
49
50 return lhs_obj1 > rhs_obj1;
51}
52
53template<ProgramType T>
55 const Individual<T>& rhs)
56{
57 // TODO: delete this one
58
59 return (lhs.fitness == rhs.fitness);
60
61 // fitness' operator== is overloaded to compare wvalues.
62 // we also check complexity equality to avoid the case where the user
63 // did not specified complexity as one of the objectives
64 // return (lhs.fitness == rhs.fitness
65 // && lhs.fitness.complexity == rhs.fitness.complexity);
66}
67
68// TODO: i could get rid of one of these
69template<ProgramType T>
71 const Individual<T>& rhs)
72{
73 return (lhs.fitness == rhs.fitness);
74}
75
76template<ProgramType T>
78{
79 // TODO: copy the population to a new vector (instead of changing inplace).
80 // also, fix this in update function
81
82 individuals.resize(0);
83
84 vector<size_t> indices;
85
86 for (int island =0; island< pop.num_islands; ++island) {
87 vector<size_t> island_indices = pop.get_island_indexes(island);
88 indices.insert(indices.end(), island_indices.begin(), island_indices.end());
89 }
90 vector<vector<int>> front = selector.fast_nds(pop, indices);
91 for (const auto& i : front[0])
92 {
93 auto& ind_ptr = pop.individuals.at(i);
94 if (ind_ptr) // Skip nullptr
95 individuals.push_back( *ind_ptr );
96 }
97
98 /* vector<size_t> front = this->sorted_front(); */
99 for (int island =0; island< pop.num_islands; ++island) {
100 auto indices = pop.get_island_indexes(island);
101
102 for (unsigned i = 0; i<indices.size(); ++i)
103 {
104 const auto& ind_ptr = pop.individuals.at(indices.at(i));
105
106 // Skip nullptr individuals (offspring slots not yet filled)
107 if (!ind_ptr)
108 continue;
109
110 const auto& t = *ind_ptr;
111
112 if (t.fitness.rank ==1){
113 // we can store a reference for the original ind, since
114 // variation operators does not change inplace. Ideally, the
115 // original individual is modified inplace just by fit(), which
116 // is a side effect that is OK to have here
117 individuals.push_back(t);
118 }
119 }
120 }
121 if (this->sort_complexity) {
122 if (this->linear_complexity)
123 std::stable_sort(individuals.begin(), individuals.end(), &sortLinearComplexity);
124 else
125 std::stable_sort(individuals.begin(), individuals.end(), &sortComplexity);
126 }
127 else
128 std::stable_sort(individuals.begin(),individuals.end(), &sortObj1);
129
130}
131
132template<ProgramType T>
134{
135 individuals.resize(0); // clear archive
136
137 vector<size_t> indices;
138
139 for (int island =0; island< pop.num_islands; ++island) {
140 vector<size_t> island_indices = pop.get_island_indexes(island);
141 indices.insert(indices.end(), island_indices.begin(), island_indices.end());
142 }
143
144 vector<vector<int>> front = selector.fast_nds(pop, indices);
145 for (const auto& i : front[0])
146 {
147 individuals.push_back( *pop.individuals.at(i) );
148 }
149
150 if (this->sort_complexity) {
151 if (this->linear_complexity)
152 std::stable_sort(individuals.begin(), individuals.end(), &sortLinearComplexity);
153 else
154 std::stable_sort(individuals.begin(), individuals.end(), &sortComplexity);
155 }
156 else {
157 std::stable_sort(individuals.begin(), individuals.end(), &sortObj1);
158 }
159
160 /* auto it = std::unique(individuals.begin(),individuals.end(), &sameFitComplexity); */
161 auto it = std::unique(individuals.begin(),individuals.end(),
163
164 individuals.resize(std::distance(individuals.begin(),it));
165}
166
167} // Pop
168} // Brush
Fitness fitness
aggregate fitness score
Definition individual.h:37
vector< size_t > get_island_indexes(int island)
Definition population.h:39
vector< std::shared_ptr< Individual< T > > > individuals
Definition population.h:19
bool in(const V &v, const T &i)
check if element is in vector.
Definition utils.h:192
< nsga2 selection operator for getting the front
Definition bandit.cpp:4
unsigned int complexity
Definition fitness.h:31
unsigned int linear_complexity
Definition fitness.h:32
vector< float > wvalues
Definition fitness.h:57
static bool sortLinearComplexity(const Individual< T > &lhs, const Individual< T > &rhs)
Definition archive.cpp:31
void set_objectives(vector< string > objectives)
Sets the objectives for the archive.
Definition archive.cpp:10
void update(Population< T > &pop, const Parameters &params)
Updates the archive with individuals from a population.
Definition archive.cpp:133
vector< Individual< T > > individuals
individual programs in the archive
Definition archive.h:27
bool sort_complexity
whether to sort archive by complexity
Definition archive.h:28
NSGA2< T > selector
using NSGA2 in survival mode (nsga2 does not implement selection)
Definition archive.h:30
void init(Population< T > &pop)
Initializes the archive with individuals from a population.
Definition archive.cpp:77
static bool sameFitComplexity(const Individual< T > &lhs, const Individual< T > &rhs)
Checks if two individuals have the same fitness complexity.
Definition archive.cpp:54
static bool sortObj1(const Individual< T > &lhs, const Individual< T > &rhs)
Sorts the population by the first objective.
Definition archive.cpp:38
static bool sortComplexity(const Individual< T > &lhs, const Individual< T > &rhs)
Sorts the population in increasing complexity.
Definition archive.cpp:20
static bool sameObjectives(const Individual< T > &lhs, const Individual< T > &rhs)
Checks if two individuals have the same objectives.
Definition archive.cpp:70
bool linear_complexity
Indicates if the user set linear_complexity instead of recursive complexity.
Definition archive.h:29
Archive()
Default constructor for the Archive struct.
Definition archive.cpp:7