26 const std::vector<bool>& flip_mask) {
27 if (genotype.size() != flip_mask.size()) {
28 throw std::invalid_argument(
"BitFlipMutationByMask: sizes must match");
30 std::vector<bool> result = genotype;
31 for (
size_t i = 0; i < flip_mask.size(); ++i) {
33 result[i] = !result[i];
45template <
typename RNG>
47 double mutation_probability, RNG& rng) {
48 if (mutation_probability < 0.0 || mutation_probability > 1.0) {
49 throw std::invalid_argument(
"BitFlipMutation: mutation_probability must be in [0, 1]");
51 std::bernoulli_distribution dist(mutation_probability);
52 std::vector<bool> mask(genotype.size());
53 for (
size_t i = 0; i < mask.size(); ++i) {
67 const std::vector<double>& noise,
68 const std::vector<bool>& apply_mask) {
69 if (genotype.size() != noise.size() || genotype.size() != apply_mask.size()) {
70 throw std::invalid_argument(
"GaussianMutationByNoise: sizes must all match");
72 std::vector<double> result(genotype.size());
73 for (
size_t i = 0; i < result.size(); ++i) {
74 result[i] = apply_mask[i] ? genotype[i] + noise[i] : genotype[i];
89template <
typename RNG>
91 double mutation_probability, RNG& rng) {
93 throw std::invalid_argument(
"GaussianMutation: sigma must be non-negative");
95 if (mutation_probability < 0.0 || mutation_probability > 1.0) {
96 throw std::invalid_argument(
"GaussianMutation: mutation_probability must be in [0, 1]");
98 std::bernoulli_distribution mask_dist(mutation_probability);
99 std::normal_distribution<double> noise_dist(0.0, sigma);
100 std::vector<bool> mask(genotype.size());
101 std::vector<double> noise(genotype.size());
102 for (
size_t i = 0; i < genotype.size(); ++i) {
103 mask[i] = mask_dist(rng);
104 noise[i] = noise_dist(rng);
129 if (!(lower < upper)) {
130 throw std::invalid_argument(
"PolynomialMutationByDraw: lower must be < upper");
132 if (x < lower || x > upper) {
133 throw std::invalid_argument(
"PolynomialMutationByDraw: x must be in [lower, upper]");
136 throw std::invalid_argument(
"PolynomialMutationByDraw: eta must be non-negative");
138 if (u < 0.0 || u > 1.0) {
139 throw std::invalid_argument(
"PolynomialMutationByDraw: u must be in [0, 1]");
142 const double range = upper - lower;
143 const double delta1 = (x - lower) / range;
144 const double delta2 = (upper - x) / range;
145 const double mut_pow = 1.0 / (eta + 1.0);
148 double xy = 1.0 - delta1;
149 double val = 2.0 * u + (1.0 - 2.0 * u) * std::pow(xy, eta + 1.0);
150 delta_q = std::pow(val, mut_pow) - 1.0;
152 double xy = 1.0 - delta2;
153 double val = 2.0 * (1.0 - u) + 2.0 * (u - 0.5) * std::pow(xy, eta + 1.0);
154 delta_q = 1.0 - std::pow(val, mut_pow);
156 double result = x + delta_q * range;
157 return std::min(std::max(result, lower), upper);
167template <
typename RNG>
169 const std::vector<double>& lower_bounds,
170 const std::vector<double>& upper_bounds,
double eta,
171 double mutation_probability, RNG& rng) {
172 if (genotype.size() != lower_bounds.size() || genotype.size() != upper_bounds.size()) {
173 throw std::invalid_argument(
"PolynomialMutation: sizes must all match");
175 if (mutation_probability < 0.0 || mutation_probability > 1.0) {
176 throw std::invalid_argument(
"PolynomialMutation: mutation_probability must be in [0, 1]");
178 std::bernoulli_distribution mask_dist(mutation_probability);
179 std::uniform_real_distribution<double> draw_dist(0.0, 1.0);
180 std::vector<double> result(genotype.size());
181 for (
size_t i = 0; i < genotype.size(); ++i) {
182 if (mask_dist(rng)) {
184 eta, draw_dist(rng));
186 result[i] = genotype[i];
Definition acquisition_functions.hpp:16
double PolynomialMutationByDraw(double x, double lower, double upper, double eta, double u)
Polynomial-mutates a single bounded gene given an explicit draw.
Definition mutation.hpp:127
std::vector< double > GaussianMutationByNoise(const std::vector< double > &genotype, const std::vector< double > &noise, const std::vector< bool > &apply_mask)
Adds noise[i] to genotype[i] wherever apply_mask[i] is true, leaves the rest unchanged.
Definition mutation.hpp:66
std::vector< bool > BitFlipMutation(const std::vector< bool > &genotype, double mutation_probability, RNG &rng)
RNG-driven wrapper: each gene flips independently with probability mutation_probability.
Definition mutation.hpp:46
std::vector< bool > BitFlipMutationByMask(const std::vector< bool > &genotype, const std::vector< bool > &flip_mask)
Flips each gene where flip_mask is true, leaves the rest unchanged.
Definition mutation.hpp:25
std::vector< double > GaussianMutation(const std::vector< double > &genotype, double sigma, double mutation_probability, RNG &rng)
RNG-driven wrapper: each gene independently receives N(0, sigma^2) noise with probability mutation_pr...
Definition mutation.hpp:90
std::vector< double > PolynomialMutation(const std::vector< double > &genotype, const std::vector< double > &lower_bounds, const std::vector< double > &upper_bounds, double eta, double mutation_probability, RNG &rng)
RNG-driven wrapper: each gene independently mutates (via PolynomialMutationByDraw) with probability m...
Definition mutation.hpp:168