OPAL (Object Oriented Parallel Accelerator Library) 2024.2
OPAL
Individual.h
Go to the documentation of this file.
1//
2// Class Individual
3// Structure for an individual in the population holding genes and objective
4// values.
5//
6// @see Types.h
7//
8// Copyright (c) 2010 - 2013, Yves Ineichen, ETH Zürich
9// All rights reserved
10//
11// Implemented as part of the PhD thesis
12// "Toward massively parallel multi-objective optimization with application to
13// particle accelerators" (https://doi.org/10.3929/ethz-a-009792359)
14//
15// This file is part of OPAL.
16//
17// OPAL is free software: you can redistribute it and/or modify
18// it under the terms of the GNU General Public License as published by
19// the Free Software Foundation, either version 3 of the License, or
20// (at your option) any later version.
21//
22// You should have received a copy of the GNU General Public License
23// along with OPAL. If not, see <https://www.gnu.org/licenses/>.
24//
25#ifndef __INDIVIDUAL_H__
26#define __INDIVIDUAL_H__
27
28#include <algorithm>
29#include <cmath>
30#include <cstdlib>
31#include <iomanip>
32#include <iostream>
33#include <limits>
34#include <memory>
35#include <set>
36#include <string>
37#include <utility>
38#include <vector>
39
41
43
44public:
46 typedef std::vector<double> genes_t;
48 typedef std::vector<std::string> names_t;
50 typedef std::vector<double> objectives_t;
52 typedef std::vector< std::pair<double, double> > bounds_t;
55
57 {}
58
60 Individual(bounds_t gene_bounds, names_t names, constraints_t constraints)
61 : bounds_m(gene_bounds)
62 , names_m(names)
63 , constraints_m(constraints)
64 {
65 genes_m.resize(bounds_m.size(), 0.0);
66 objectives_m.resize(bounds_m.size(), 0.0);
67
68 // names should be equal length to bounds
69 if (names_m.size() != bounds_m.size()) {
70 // shouldn't happen
71 std::cerr << "Individual::Individual(): names not equal length to bounds, shouldn't happen exiting" << std::endl;
72 exit(1);
73 }
74
75 int iter = 0;
76 while (iter < 100) { // somewhat arbitrary limit
77 for (std::size_t i=0; i < bounds_m.size(); i++) {
78 new_gene(i);
79 }
80 // check constraints
81 bool allSatisfied = checkConstraints();
82 if (allSatisfied == true) break;
83 // else next try
84 iter++;
85 }
86 }
87
89 Individual(std::shared_ptr<Individual> individual) {
90 genes_m = genes_t(individual->genes_m);
91 objectives_m = objectives_t(individual->objectives_m);
92 bounds_m = bounds_t(individual->bounds_m);
93 names_m = names_t(individual->names_m);
94 constraints_m = constraints_t(individual->constraints_m);
95 id_m = individual->id_m;
96 }
97
99 void writeState(std::ostream& os) const {
100 os << std::setprecision(std::numeric_limits<double>::max_digits10);
101 os << id_m << ' ' << genes_m.size();
102 for (double g : genes_m) os << ' ' << g;
103 os << ' ' << objectives_m.size();
104 for (double o : objectives_m) os << ' ' << o;
105 os << '\n';
106 }
107
109 void readState(std::istream& is) {
110 std::size_t ngenes = 0, nobjs = 0;
111 is >> id_m >> ngenes;
112 genes_m.resize(ngenes);
113 for (double& g : genes_m) is >> g;
114 is >> nobjs;
115 objectives_m.resize(nobjs);
116 for (double& o : objectives_m) is >> o;
117 }
118
121 double new_gene(std::size_t gene_idx) {
122 double max = std::max(bounds_m[gene_idx].first, bounds_m[gene_idx].second);
123 double min = std::min(bounds_m[gene_idx].first, bounds_m[gene_idx].second);
124 double delta = std::abs(max - min);
125 genes_m[gene_idx] = std::rand() / (RAND_MAX + 1.0) * delta + min;
126 return genes_m[gene_idx];
127 }
129 bool viable() {
130 return checkBounds() && checkConstraints();
131 }
132
138 unsigned int id_m = 0;
139
140private:
142 bool checkBounds() {
143 for (std::size_t i=0; i < bounds_m.size(); i++) {
144 double value = genes_m[i];
145 double max = std::max(bounds_m[i].first, bounds_m[i].second);
146 double min = std::min(bounds_m[i].first, bounds_m[i].second);
147 bool is_valid = (value >= min && value<= max);
148 if (is_valid == false) {
149 return false;
150 }
151 }
152 return true;
153 }
154
157 for (auto namedConstraint : constraints_m) {
158 Expressions::Expr_t *constraint = namedConstraint.second;
159 std::set<std::string> req_vars = constraint->getReqVars();
160 variableDictionary_t variable_dictionary;
161 // fill variable dictionary. all required variables should be genes.
162 for (std::string req_var : req_vars) {
163 auto it = std::find(names_m.begin(),names_m.end(),req_var);
164 if (it==names_m.end()) {
165 // should not happen
166 std::cerr << "Individual::checkConstraints(): " << req_var << " is not a design variable" << std::endl;
167 exit(1);
168 }
169 std::size_t gene_idx = std::distance(names_m.begin(),it);
170 double value = genes_m[gene_idx];
171 variable_dictionary.insert(std::pair<std::string, double>(req_var, value));
172 }
173 Expressions::Result_t result =
174 constraint->evaluate(variable_dictionary);
175
176 double evaluation = std::get<0>(result);
177 bool is_valid = std::get<1>(result);
178
179 if (is_valid==false || evaluation==0) {
180 return false;
181 }
182 }
183 return true;
184 }
191};
192
193#endif
T::PETE_Expr_t::PETE_Return_t max(const PETE_Expr< T > &expr, NDIndex< D > &loc)
T::PETE_Expr_t::PETE_Return_t min(const PETE_Expr< T > &expr, NDIndex< D > &loc)
std::map< std::string, double > variableDictionary_t
Definition Expression.h:50
std::map< std::string, Expressions::Expr_t * > Named_t
type of an expressions with a name
Definition Expression.h:68
std::tuple< double, bool > Result_t
Definition Expression.h:60
Expressions::Result_t evaluate(const variableDictionary_t &vars)
evaluate an expression given a value dictionary of free variables
Definition Expression.h:125
const std::set< std::string > & getReqVars() const
Definition Expression.h:115
std::vector< std::string > names_t
gene names
Definition Individual.h:48
unsigned int id_m
id
Definition Individual.h:138
genes_t genes_m
genes of an individual
Definition Individual.h:134
names_t names_m
gene names
Definition Individual.h:188
objectives_t objectives_m
values of objectives of an individual
Definition Individual.h:136
bool checkBounds()
check bounds
Definition Individual.h:142
std::vector< std::pair< double, double > > bounds_t
bounds on design variables
Definition Individual.h:52
bool viable()
test if individual within bounds and constraints
Definition Individual.h:129
Individual(bounds_t gene_bounds, names_t names, constraints_t constraints)
create a new individual and initialize with random genes
Definition Individual.h:60
bounds_t bounds_m
bounds on each gene
Definition Individual.h:186
constraints_t constraints_m
constraints that depend only on design variables
Definition Individual.h:190
std::vector< double > genes_t
representation of genes
Definition Individual.h:46
bool checkConstraints()
check if all constraints on design variables are checked
Definition Individual.h:156
std::vector< double > objectives_t
objectives array
Definition Individual.h:50
double new_gene(std::size_t gene_idx)
Definition Individual.h:121
Expressions::Named_t constraints_t
constraints
Definition Individual.h:54
Individual(std::shared_ptr< Individual > individual)
copy another individual
Definition Individual.h:89
void readState(std::istream &is)
read this individual's state from a stream, replaces boost::serialization
Definition Individual.h:109
void writeState(std::ostream &os) const
write this individual's state to a stream, replaces boost::serialization
Definition Individual.h:99