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 return (lhs.fitness == rhs.fitness);
58
59 // fitness' operator== is overloaded to compare wvalues.
60 // we also check complexity equality to avoid the case where the user
61 // did not specified complexity as one of the objectives
62}
63
64template<ProgramType T>
66{
67 // TODO: copy the population to a new vector (instead of changing inplace).
68 // also, fix this in update function
69
70 individuals.resize(0);
71
72 vector<size_t> indices;
73
74 for (int island =0; island< pop.num_islands; ++island) {
75 vector<size_t> island_indices = pop.get_island_indexes(island);
76 indices.insert(indices.end(), island_indices.begin(), island_indices.end());
77 }
78 vector<vector<int>> front = selector.fast_nds(pop, indices);
79 for (const auto& i : front[0])
80 {
81 auto& ind_ptr = pop.individuals.at(i);
82 if (ind_ptr) // Skip nullptr
83 individuals.push_back( *ind_ptr );
84 }
85
86 /* vector<size_t> front = this->sorted_front(); */
87 for (int island =0; island< pop.num_islands; ++island) {
88 auto indices = pop.get_island_indexes(island);
89
90 for (unsigned i = 0; i<indices.size(); ++i)
91 {
92 const auto& ind_ptr = pop.individuals.at(indices.at(i));
93
94 // Skip nullptr individuals (offspring slots not yet filled)
95 if (!ind_ptr)
96 continue;
97
98 const auto& t = *ind_ptr;
99
100 if (t.fitness.rank ==1){
101 // we can store a reference for the original ind, since
102 // variation operators does not change inplace. Ideally, the
103 // original individual is modified inplace just by fit(), which
104 // is a side effect that is OK to have here
105 individuals.push_back(t);
106 }
107 }
108 }
109 if (this->sort_complexity) {
110 if (this->linear_complexity)
111 std::stable_sort(individuals.begin(), individuals.end(), &sortLinearComplexity);
112 else
113 std::stable_sort(individuals.begin(), individuals.end(), &sortComplexity);
114 }
115 else
116 std::stable_sort(individuals.begin(),individuals.end(), &sortObj1);
117
118}
119
120template<ProgramType T>
122{
123 individuals.resize(0); // clear archive
124
125 vector<size_t> indices;
126
127 for (int island =0; island< pop.num_islands; ++island) {
128 vector<size_t> island_indices = pop.get_island_indexes(island);
129 indices.insert(indices.end(), island_indices.begin(), island_indices.end());
130 }
131
132 vector<vector<int>> front = selector.fast_nds(pop, indices);
133 for (const auto& i : front[0])
134 {
135 individuals.push_back( *pop.individuals.at(i) );
136 }
137
138 if (this->sort_complexity) {
139 if (this->linear_complexity)
140 std::stable_sort(individuals.begin(), individuals.end(), &sortLinearComplexity);
141 else
142 std::stable_sort(individuals.begin(), individuals.end(), &sortComplexity);
143 }
144 else {
145 std::stable_sort(individuals.begin(), individuals.end(), &sortObj1);
146 }
147
148 auto it = std::unique(individuals.begin(),individuals.end(),
150
151 individuals.resize(std::distance(individuals.begin(),it));
152}
153
154} // Pop
155} // Brush
156
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:3
unsigned int complexity
Definition fitness.h:31
unsigned int linear_complexity
Definition fitness.h:32
vector< float > wvalues
Definition fitness.h:57
The Archive struct represents a collection of individual programs.
Definition archive.h:26
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:121
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:65
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:54
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