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 // dealing with islands --> fast nds for each island
85 for (int island =0; island< pop.num_islands; ++island) {
86 vector<size_t> indices = pop.get_island_indexes(island);
87
88 selector.fast_nds(pop, indices);
89 }
90
91 // OBS: fast_nds will change all individual fitness inplace.
92 // It will update the values for dcounter, rank, and dominated individuals.
93
94 // TODO: fix this way of getting pareto front (the pareto front of different islands combined will not necessarily be the final pareto front). Also fix this in update
95
96 /* vector<size_t> front = this->sorted_front(); */
97 for (int island =0; island< pop.num_islands; ++island) {
98 auto indices = pop.get_island_indexes(island);
99
100 for (unsigned i = 0; i<indices.size(); ++i)
101 {
102 const auto& t = *pop.individuals.at(indices.at(i));
103
104 if (t.fitness.rank ==1){
105 // we can store a reference for the original ind, since
106 // variation operators does not change inplace. Ideally, the
107 // original individual is modified inplace just by fit(), which
108 // is a side effect that is OK to have here
109 individuals.push_back(t);
110 }
111 }
112 }
113 if (this->sort_complexity) {
114 if (this->linear_complexity)
115 std::sort(individuals.begin(), individuals.end(), &sortLinearComplexity);
116 else
117 std::sort(individuals.begin(), individuals.end(), &sortComplexity);
118 }
119 else
120 std::sort(individuals.begin(),individuals.end(), &sortObj1);
121
122}
123
124template<ProgramType T>
126{
127 individuals.resize(0); // clear archive
128
129 // refill archive with new pareto fronts (one pareto front for each island!)
130 // TODO: refill with fast nds just like hall of fame
131 for (int island =0; island< pop.num_islands; ++island) {
132 vector<size_t> indices = pop.get_island_indexes(island);
133
134 // TODO: can i just call fast nds with all indexes in indices?
135 vector<vector<int>> front = selector.fast_nds(pop, indices);
136 for (const auto& i : front[0])
137 {
138 individuals.push_back( *pop.individuals.at(i) );
139 }
140 }
141
142 if (this->sort_complexity) {
143 if (this->linear_complexity)
144 std::sort(individuals.begin(), individuals.end(), &sortLinearComplexity);
145 else
146 std::sort(individuals.begin(), individuals.end(), &sortComplexity);
147 }
148 else {
149 std::sort(individuals.begin(), individuals.end(), &sortObj1);
150 }
151
152 /* auto it = std::unique(individuals.begin(),individuals.end(), &sameFitComplexity); */
153 auto it = std::unique(individuals.begin(),individuals.end(),
155
156 individuals.resize(std::distance(individuals.begin(),it));
157}
158
159} // Pop
160} // 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:125
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