10template<ProgramType T>
17template<ProgramType T>
38template<ProgramType T>
49 std::remove_if(island_pool.begin(), island_pool.end(),
50 [&pop](
size_t idx) { return pop.individuals.at(idx) == nullptr; }),
55 if (island_pool.empty())
63 auto front =
fast_nds(pop, island_pool);
64 for (
size_t i = 0; i< front.size(); i++)
69 vector<size_t> selected(0);
70 for (
int i = 0; i < island_pool.size(); ++i)
73 *
r.select_randomly(island_pool.begin(), island_pool.end()),
74 *
r.select_randomly(island_pool.begin(), island_pool.end()));
76 selected.push_back(winner);
81template<ProgramType T>
88 std::vector<size_t> island_pool;
91 island_pool.insert(island_pool.end(), indexes.begin(), indexes.end());
96 std::remove_if(island_pool.begin(), island_pool.end(),
97 [&pop](
size_t idx) { return pop.individuals.at(idx) == nullptr; }),
102 if (island_pool.empty()) {
104 "NSGA2::survive - island_pool is empty after filtering nullptrs. "
105 "This suggests population was not properly initialized or variation failed."));
109 auto front =
fast_nds(pop, island_pool);
112 vector<size_t> selected;
118 && ( selected.size() + front.at(i).size() < params.
pop_size )
121 std::vector<int>& Fi = front.at(i);
125 for (
int j = 0; j < Fi.size(); ++j)
126 selected.push_back(Fi.at(j));
133 std::stable_sort(front.at(i).begin(),front.at(i).end(),
sort_n(pop));
136 const int extra = params.
pop_size - selected.size();
139 const int available = front.at(i).size();
140 const int to_add = std::min(extra, available);
142 for (
int j = 0; j < to_add; ++j)
143 selected.push_back(front.at(i).at(j));
146 if (selected.size() != params.
pop_size) {
147 throw std::runtime_error(fmt::format(
148 "NSGA2 survive: Could not select {} survivors. Only found {} valid individuals in population.",
157template<ProgramType T>
164 vector<vector<int>> front;
169 for (
int i = 0; i < island_pool.size(); ++i) {
171 std::vector<unsigned int> dom;
176 for (
int j = 0; j < island_pool.size(); ++j) {
180 int compare = p->fitness.dominates(q.
fitness);
183 dom.push_back(island_pool[j]);
184 }
else if (compare == -1) {
189 p->fitness.dcounter = dcount;
190 p->fitness.dominated = dom;
193 if (p->fitness.dcounter == 0) {
195 p->fitness.set_rank(1);
197 front.at(0).push_back(island_pool[i]);
207 std::stable_sort(front.at(0).begin(), front.at(0).end());
210 while (front.at(fi-1).size() > 0) {
211 std::vector<int>& fronti = front.at(fi-1);
213 for (
int i = 0; i < fronti.size(); ++i) {
224 q->fitness.dcounter -= 1;
226 if (q->fitness.dcounter == 0) {
229 q->fitness.set_rank(fi+1);
242template<ProgramType T>
248 std::vector<int> F = front.at(fronti);
254 const int fsize = F.size();
257 for (
int i = 0; i < fsize; ++i)
258 pop.
individuals.at(F.at(i))->fitness.set_crowding_dist(0.0f);
262 const int limit = pop.
individuals.at(0)->fitness.get_wvalues().size();
265 for (
int m = 0; m < limit; ++m) {
272 pop.
individuals.at(F.at(0))->fitness.crowding_dist = std::numeric_limits<float>::max();
274 pop.
individuals.at(F.at(fsize-1))->fitness.crowding_dist = std::numeric_limits<float>::max();
276 float first_of_front = pop.
individuals.at(F.at(0))->fitness.get_wvalues().at(m);
277 float last_of_front = pop.
individuals.at(F.at(fsize-1))->fitness.get_wvalues().at(m);
278 for (
int i = 1; i < fsize-1; ++i)
280 if (pop.
individuals.at(F.at(i))->fitness.crowding_dist != std::numeric_limits<float>::max())
282 float next_of_front = pop.
individuals.at(F.at(i+1))->fitness.get_wvalues().at(m);
283 float prev_of_front = pop.
individuals.at(F.at(i-1))->fitness.get_wvalues().at(m);
286 pop.
individuals.at(F.at(i))->fitness.crowding_dist +=
287 (next_of_front - prev_of_front) / (last_of_front - first_of_front);
Fitness fitness
aggregate fitness score
vector< size_t > get_island_indexes(int island)
vector< std::shared_ptr< Individual< T > > > individuals
void crowding_distance(Population< T > &, vector< vector< int > > &, int)
size_t tournament(Population< T > &pop, size_t i, size_t j) const
vector< size_t > survive(Population< T > &pop, int island, const Parameters &p)
survival according to the survival scheme of NSGA-II
vector< vector< int > > fast_nds(Population< T > &, vector< size_t > &)
vector< size_t > select(Population< T > &pop, int island, const Parameters &p)
selection according to the survival scheme of NSGA-II
#define HANDLE_ERROR_THROW(err)
< nsga2 selection operator for getting the front
float crowding_dist
crowding distance on the Pareto front
vector< unsigned int > dominated
individual indices this dominates
int dominates(const Fitness &b) const
set obj vector given a string of objective names
sort based on objective m
sort based on rank, breaking ties with crowding distance