OPAL (Object Oriented Parallel Accelerator Library) 2024.2
OPAL
Population.h
Go to the documentation of this file.
1//
2// Class Population
3// Managing a population of individuals. We maintain two sets: a set of all
4// (evaluated) individuals in the population and a set of new potential
5// individuals (the selector decides which individuals join the population),
6// called 'stagingArea'.
7// Most operations work on the 'stagingArea', population is kept for
8// visualization purposes.
9//
10// Copyright (c) 2010 - 2013, Yves Ineichen, ETH Zürich
11// All rights reserved
12//
13// Implemented as part of the PhD thesis
14// "Toward massively parallel multi-objective optimization with application to
15// particle accelerators" (https://doi.org/10.3929/ethz-a-009792359)
16//
17// This file is part of OPAL.
18//
19// OPAL is free software: you can redistribute it and/or modify
20// it under the terms of the GNU General Public License as published by
21// the Free Software Foundation, either version 3 of the License, or
22// (at your option) any later version.
23//
24// You should have received a copy of the GNU General Public License
25// along with OPAL. If not, see <https://www.gnu.org/licenses/>.
26//
27#ifndef __POPULATION_H__
28#define __POPULATION_H__
29
30#include <map>
31#include <memory>
32#include <vector>
33#include <utility>
34#include <queue>
35#include <set>
36#include <cmath>
37#include <fstream>
38#include <sstream>
39
41
42
43template< class Individual_t >
45
46public:
48 last_identity = 0;
49 }
50
52
53 typedef typename Individual_t::genes_t genes_t;
54 typedef std::shared_ptr<Individual_t> individual;
55 typedef std::pair< unsigned int, individual > ind_t;
56
58 typedef typename std::map<unsigned int, individual>::iterator indItr_t;
59
65 unsigned int add_individual(individual ind) {
66
67 unsigned int id = getFreeID();
68 stagingArea.insert(ind_t(id, ind));
69 ind->id_m = id;
70 //std::cout << "+++ staging id = " << id << "\xd";
71 return id;
72 }
73
75
76 indItr_t it = stagingArea.begin();
77 while(it != stagingArea.end()) {
78 if(it->second == ind) {
79 if(it->first == last_identity-1)
81 else
82 freeids.push(it->first);
83
84 //std::cout << "--- removing id = " << it->first << "\xd";
85 stagingArea.erase(it);
86 break;
87 }
88 it++;
89 }
90 }
91
98 individual get_individual(int identity) {
99 indItr_t it;
100 if(identity == -1)
101 it = individuals.begin();
102 else {
103 it = individuals.find(identity);
104 if( it == individuals.end() )
105 return individual();
106 }
107
108 return it->second;
109 }
110
117 individual get_staging(int identity) {
118 indItr_t it;
119 if(identity == -1)
120 it = stagingArea.begin();
121 else {
122 it = stagingArea.find(identity);
123 if( it == stagingArea.end() )
124 return individual();
125 }
126
127 return it->second;
128 }
129
130
131 void commit_individuals(std::set<unsigned int> ids) {
132
133 for (unsigned int id : ids) {
134 //std::cout << "--+ committing id = " << id << "\xd";
135 individual ind = get_staging(id);
136 individuals.insert(ind_t(id, ind));
137 stagingArea.erase(id);
138 }
139 }
140
146 void keepSurvivors(std::set<unsigned int> survivors) {
147
148 indItr_t it = individuals.begin();
149 while(it != individuals.end()) {
150 if( survivors.count(it->first) == 0 ) {
151 if(it->first == last_identity-1)
153 else
154 freeids.push(it->first);
155
156 individuals.erase(it++);
157 } else
158 it++;
159 }
160 }
161
162
164 //XXX: currently O(n): add a fast look-up table?
166
167 for(ind_t ind : individuals) {
168 if( ind_genes == ind.second->genes_m )
169 return true;
170 }
171
172 return false;
173 }
174
175
176 double computeHypervolume(size_t island_id, const std::vector<double>& referencePoint) {
177 // protection check
178 if (individuals.empty() == true) return -1;
179
180 std::ofstream file;
181 std::ostringstream filename;
182 filename << "hypervol.dat_" << island_id;
183 file.open(filename.str().c_str(), std::ios::out);
184
185 file << "#" << std::endl;
186
187 indItr_t it;
188 for(it = individuals.begin(); it != individuals.end(); it++) {
189
190 individual temp = it->second;
191 for(size_t i=0; i<temp->objectives_m.size(); i++)
192 file << temp->objectives_m[i] << " ";
193 if (!temp->objectives_m.empty())
194 file << std::endl;
195 }
196
197 file << "#" << std::endl;
198
199 file.flush();
200 file.close();
201
202 return Hypervolume::FromFile(filename.str(), referencePoint);
203 }
204
205
207 individuals.insert(stagingArea.begin(), stagingArea.end());
208 stagingArea.clear();
209 }
210
211
213 indItr_t stagingBegin() { return stagingArea.begin(); }
215 indItr_t stagingEnd() { return stagingArea.end(); }
216
217
222 unsigned int size() const { return individuals.size(); }
223
225 indItr_t begin() { return individuals.begin(); }
227 indItr_t end() { return individuals.end(); }
229 indItr_t erase(indItr_t it) { return individuals.erase(it); }
230
231private:
232
234 std::map<unsigned int, individual > individuals;
235
237 std::map<unsigned int, individual > stagingArea;
238
240 std::queue<unsigned int> freeids;
241
243 unsigned int last_identity;
244
249 unsigned int getFreeID() {
250
251 unsigned int id = 0;
252 if(freeids.empty()) {
253 id = last_identity;
255 } else {
256 id = freeids.front();
257 freeids.pop();
258 }
259
260 return id;
261 }
262};
263
264#endif
double FromFile(std::string file, const std::vector< double > &referencePoint)
std::map< unsigned int, individual > stagingArea
staging area for individuals probably joining population
Definition Population.h:237
unsigned int getFreeID()
Definition Population.h:249
indItr_t erase(indItr_t it)
erase individual
Definition Population.h:229
std::pair< unsigned int, individual > ind_t
Definition Population.h:55
unsigned int size() const
Definition Population.h:222
std::map< unsignedint, individual >::iterator indItr_t
population iterator type
Definition Population.h:58
double computeHypervolume(size_t island_id, const std::vector< double > &referencePoint)
Definition Population.h:176
Individual_t::genes_t genes_t
Definition Population.h:53
std::map< unsigned int, individual > individuals
population container holding all individuals
Definition Population.h:234
void commit_individuals()
Definition Population.h:206
bool isRepresentedInPopulation(genes_t ind_genes)
check if a gene set is already represented in the population
Definition Population.h:165
individual get_individual(int identity)
Definition Population.h:98
unsigned int add_individual(individual ind)
Definition Population.h:65
void remove_individual(individual ind)
Definition Population.h:74
unsigned int last_identity
last used (= next free) ID
Definition Population.h:243
indItr_t stagingBegin()
iterator begin on staging area
Definition Population.h:213
std::queue< unsigned int > freeids
queue to handle free individual IDs
Definition Population.h:240
indItr_t end()
iterator end on population container
Definition Population.h:227
void commit_individuals(std::set< unsigned int > ids)
Definition Population.h:131
indItr_t begin()
iterator begin on population container
Definition Population.h:225
indItr_t stagingEnd()
iterator end on staging area
Definition Population.h:215
individual get_staging(int identity)
Definition Population.h:117
std::shared_ptr< Individual_t > individual
Definition Population.h:54
void keepSurvivors(std::set< unsigned int > survivors)
Definition Population.h:146