Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bounds checking for initial population in optimizers evolve process #568

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions src/algorithms/bee_colony.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,26 @@ population bee_colony::evolve(population pop) const
if (m_gen == 0u) {
return pop;
}
// make sure all genes respect the bounds
for (decltype(NP) i = 0u; i < NP; ++i) {
for (decltype(dim) j = 0u; j < dim; ++j) {
double x = pop.get_x()[i][j];
if (std::isnan(x)) {
pagmo_throw(std::invalid_argument, "Individual " + std::to_string(i) + " has a gene " + std::to_string(j)
+ " equal to NaN" + std::to_string(x));
}

if (std::isinf(x)) {
pagmo_throw(std::invalid_argument, "Individual " + std::to_string(i) + " has a gene " + std::to_string(j)
+ " equal to infinity" + std::to_string(x));
}

if (x < bounds.first[j] || x > bounds.second[j]) {
pagmo_throw(std::invalid_argument, "Individual " + std::to_string(i) + " has a gene " + std::to_string(j)
+ " out of bounds: " + std::to_string(x));
}
}
}
// ---------------------------------------------------------------------------------------------------------

// No throws, all valid: we clear the logs
Expand Down
24 changes: 24 additions & 0 deletions src/algorithms/cmaes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,30 @@ population cmaes::evolve(population pop) const
+ this->get_name() + " cannot deal with it.");
}
}
// Verify all decision variables respect the bounds if force_bounds is true
if (m_force_bounds)
{
for (decltype(lam) i = 0u; i < lam; ++i) {
for (decltype(dim) j = 0u; j < dim; ++j) {
double x = pop.get_x()[i][j];
if (std::isnan(x)) {
pagmo_throw(std::invalid_argument, "Individual " + std::to_string(i) + " has a gene " + std::to_string(j)
+ " equal to NaN" + std::to_string(x));
}

if (std::isinf(x)) {
pagmo_throw(std::invalid_argument, "Individual " + std::to_string(i) + " has a gene " + std::to_string(j)
+ " equal to infinity" + std::to_string(x));
}

if (x < bounds.first[j] || x > bounds.second[j]) {
pagmo_throw(std::invalid_argument, "Individual " + std::to_string(i) + " has a gene " + std::to_string(j)
+ " out of bounds: " + std::to_string(x));
}
}
}
}

// Get out if there is nothing to do.
if (m_gen == 0u) {
return pop;
Expand Down
21 changes: 21 additions & 0 deletions src/algorithms/compass_search.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ population compass_search::evolve(population pop) const
// We store some useful variables
const auto &prob = pop.get_problem(); // This is a const reference, so using set_seed for example will not be
// allowed
auto NP = pop.size();
auto dim = prob.get_nx(); // This getter does not return a const reference but a copy
const auto bounds = prob.get_bounds();
const auto &lb = bounds.first;
Expand Down Expand Up @@ -105,6 +106,26 @@ population compass_search::evolve(population pop) const
if (m_max_fevals == 0u) {
return pop;
}
// Verify all decision variables respect the bounds
for (decltype(NP) i = 0u; i < NP; ++i) {
for (decltype(dim) j = 0u; j < dim; ++j) {
double x = pop.get_x()[i][j];
if (std::isnan(x)) {
pagmo_throw(std::invalid_argument, "Individual " + std::to_string(i) + " has a gene " + std::to_string(j)
+ " equal to NaN" + std::to_string(x));
}

if (std::isinf(x)) {
pagmo_throw(std::invalid_argument, "Individual " + std::to_string(i) + " has a gene " + std::to_string(j)
+ " equal to infinity" + std::to_string(x));
}

if (x < bounds.first[j] || x > bounds.second[j]) {
pagmo_throw(std::invalid_argument, "Individual " + std::to_string(i) + " has a gene " + std::to_string(j)
+ " out of bounds: " + std::to_string(x));
}
}
}
// ---------------------------------------------------------------------------------------------------------

// No throws, all valid: we clear the logs
Expand Down
21 changes: 21 additions & 0 deletions src/algorithms/cstrs_self_adaptive.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,7 @@ population cstrs_self_adaptive::evolve(population pop) const
auto nec = prob.get_nec(); // This getter does not return a const reference but a copy
const auto bounds = prob.get_bounds();
auto NP = pop.size();
auto dim = prob.get_nx();

auto fevals0 = prob.get_fevals(); // discount for the already made fevals
unsigned count = 1u; // regulates the screen output
Expand All @@ -429,6 +430,26 @@ population cstrs_self_adaptive::evolve(population pop) const
pagmo_throw(std::invalid_argument,
"Cannot use " + prob.get_name() + " on a population with less than 4 individuals");
}
// Verify all decision variables respect the bounds
for (decltype(NP) i = 0u; i < NP; ++i) {
for (decltype(dim) j = 0u; j < dim; ++j) {
double x = pop.get_x()[i][j];
if (std::isnan(x)) {
pagmo_throw(std::invalid_argument, "Individual " + std::to_string(i) + " has a gene " + std::to_string(j)
+ " equal to NaN" + std::to_string(x));
}

if (std::isinf(x)) {
pagmo_throw(std::invalid_argument, "Individual " + std::to_string(i) + " has a gene " + std::to_string(j)
+ " equal to infinity" + std::to_string(x));
}

if (x < bounds.first[j] || x > bounds.second[j]) {
pagmo_throw(std::invalid_argument, "Individual " + std::to_string(i) + " has a gene " + std::to_string(j)
+ " out of bounds: " + std::to_string(x));
}
}
}
// ---------------------------------------------------------------------------------------------------------

// No throws, all valid: we clear the logs
Expand Down
20 changes: 20 additions & 0 deletions src/algorithms/de.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,26 @@ population de::evolve(population pop) const
pagmo_throw(std::invalid_argument, get_name() + " needs at least 5 individuals in the population, "
+ std::to_string(pop.size()) + " detected");
}
// Verify all decision variables respect the bounds
for (decltype(NP) i = 0u; i < NP; ++i) {
for (decltype(dim) j = 0u; j < dim; ++j) {
double x = pop.get_x()[i][j];
if (std::isnan(x)) {
pagmo_throw(std::invalid_argument, "Individual " + std::to_string(i) + " has a gene " + std::to_string(j)
+ " equal to NaN" + std::to_string(x));
}

if (std::isinf(x)) {
pagmo_throw(std::invalid_argument, "Individual " + std::to_string(i) + " has a gene " + std::to_string(j)
+ " equal to infinity" + std::to_string(x));
}

if (x < bounds.first[j] || x > bounds.second[j]) {
pagmo_throw(std::invalid_argument, "Individual " + std::to_string(i) + " has a gene " + std::to_string(j)
+ " out of bounds: " + std::to_string(x));
}
}
}
// ---------------------------------------------------------------------------------------------------------

// No throws, all valid: we clear the logs
Expand Down
20 changes: 20 additions & 0 deletions src/algorithms/de1220.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,26 @@ population de1220::evolve(population pop) const
pagmo_throw(std::invalid_argument, get_name() + " needs at least 7 individuals in the population, "
+ std::to_string(pop.size()) + " detected");
}
// Verify all decision variables respect the bounds
for (decltype(NP) i = 0u; i < NP; ++i) {
for (decltype(dim) j = 0u; j < dim; ++j) {
double x = pop.get_x()[i][j];
if (std::isnan(x)) {
pagmo_throw(std::invalid_argument, "Individual " + std::to_string(i) + " has a gene " + std::to_string(j)
+ " equal to NaN" + std::to_string(x));
}

if (std::isinf(x)) {
pagmo_throw(std::invalid_argument, "Individual " + std::to_string(i) + " has a gene " + std::to_string(j)
+ " equal to infinity" + std::to_string(x));
}

if (x < bounds.first[j] || x > bounds.second[j]) {
pagmo_throw(std::invalid_argument, "Individual " + std::to_string(i) + " has a gene " + std::to_string(j)
+ " out of bounds: " + std::to_string(x));
}
}
}
// ---------------------------------------------------------------------------------------------------------

// No throws, all valid: we clear the logs
Expand Down
21 changes: 21 additions & 0 deletions src/algorithms/gaco.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ population gaco::evolve(population pop) const
auto n_x = prob.get_nx(); // This getter does not return a const reference but a copy of the number of
// all the variables
auto pop_size = pop.size(); // Population size
auto bounds = prob.get_bounds(); // Bounds of the problem
unsigned count_screen = 1u; // regulates the screen output

// Note that the number of equality and inequality constraints has to be set up manually in the problem
Expand Down Expand Up @@ -167,6 +168,26 @@ population gaco::evolve(population pop) const
pagmo_throw(std::invalid_argument, "Multiple objectives detected in " + prob.get_name() + " instance. "
+ get_name() + " cannot deal with them");
}
// Verify all decision variables respect the bounds
for (decltype(pop_size) i = 0u; i < pop_size; ++i) {
for (decltype(n_x) j = 0u; j < n_x; ++j) {
double x = pop.get_x()[i][j];
if (std::isnan(x)) {
pagmo_throw(std::invalid_argument, "Individual " + std::to_string(i) + " has a gene " + std::to_string(j)
+ " equal to NaN" + std::to_string(x));
}

if (std::isinf(x)) {
pagmo_throw(std::invalid_argument, "Individual " + std::to_string(i) + " has a gene " + std::to_string(j)
+ " equal to infinity" + std::to_string(x));
}

if (x < bounds.first[j] || x > bounds.second[j]) {
pagmo_throw(std::invalid_argument, "Individual " + std::to_string(i) + " has a gene " + std::to_string(j)
+ " out of bounds: " + std::to_string(x));
}
}
}

// ---------------------------------------------------------------------------------------------------------

Expand Down
20 changes: 20 additions & 0 deletions src/algorithms/gwo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,26 @@ population gwo::evolve(population pop) const
pagmo_throw(std::invalid_argument, get_name() + " needs at least 3 individuals in the population, "
+ std::to_string(pop.size()) + " detected");
}
// Verify all decision variables respect the bounds
for (decltype(NP) i = 0u; i < NP; ++i) {
for (decltype(dim) j = 0u; j < dim; ++j) {
double x = pop.get_x()[i][j];
if (std::isnan(x)) {
pagmo_throw(std::invalid_argument, "Individual " + std::to_string(i) + " has a gene " + std::to_string(j)
+ " equal to NaN" + std::to_string(x));
}

if (std::isinf(x)) {
pagmo_throw(std::invalid_argument, "Individual " + std::to_string(i) + " has a gene " + std::to_string(j)
+ " equal to infinity" + std::to_string(x));
}

if (x < bounds.first[j] || x > bounds.second[j]) {
pagmo_throw(std::invalid_argument, "Individual " + std::to_string(i) + " has a gene " + std::to_string(j)
+ " out of bounds: " + std::to_string(x));
}
}
}
// ---------------------------------------------------------------------------------------------------------

// No throws, all valid: we clear the logs
Expand Down
33 changes: 27 additions & 6 deletions src/algorithms/ihs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ population ihs::evolve(population pop) const
// We store some useful properties
const auto &prob = pop.get_problem(); // This is a const reference, so using set_seed for example will not be
// allowed
auto NP = pop.size();
auto dim = prob.get_nx();
auto int_dim = prob.get_nix();
const auto bounds = prob.get_bounds();
Expand All @@ -90,7 +91,7 @@ population ihs::evolve(population pop) const
if (m_gen == 0u) {
return pop;
}
if (!pop.size()) {
if (!NP) {
pagmo_throw(std::invalid_argument, get_name() + " does not work on an empty population");
}
if (prob.get_nc() != 0u && prob.get_nobj() > 1u) {
Expand All @@ -102,6 +103,26 @@ population ihs::evolve(population pop) const
pagmo_throw(std::invalid_argument,
"The problem appears to be stochastic " + get_name() + " cannot deal with it");
}
// Verify all decision variables respect the bounds
for (decltype(NP) i = 0u; i < NP; ++i) {
for (decltype(dim) j = 0u; j < dim; ++j) {
double x = pop.get_x()[i][j];
if (std::isnan(x)) {
pagmo_throw(std::invalid_argument, "Individual " + std::to_string(i) + " has a gene " + std::to_string(j)
+ " equal to NaN" + std::to_string(x));
}

if (std::isinf(x)) {
pagmo_throw(std::invalid_argument, "Individual " + std::to_string(i) + " has a gene " + std::to_string(j)
+ " equal to infinity" + std::to_string(x));
}

if (x < bounds.first[j] || x > bounds.second[j]) {
pagmo_throw(std::invalid_argument, "Individual " + std::to_string(i) + " has a gene " + std::to_string(j)
+ " out of bounds: " + std::to_string(x));
}
}
}
// ---------------------------------------------------------------------------------------------------------

// No throws, all valid: we clear the logs
Expand All @@ -112,15 +133,15 @@ population ihs::evolve(population pop) const
lu_diff[i] = ub[i] - lb[i];
}
// Distributions used
std::uniform_int_distribution<decltype(pop.size())> uni_int(0, pop.size() - 1u); // to pick an individual
std::uniform_int_distribution<decltype(NP)> uni_int(0, NP - 1u); // to pick an individual
std::uniform_real_distribution<double> drng(0., 1.); // to generate a number in [0, 1)

// Used for parameter control
const double c = std::log(m_bw_min / m_bw_max) / m_gen;

// Declarations
vector_double new_x(dim, 0.);
std::vector<vector_double::size_type> best_idxs(pop.size());
std::vector<vector_double::size_type> best_idxs(NP);

// Main loop
for (decltype(m_gen) gen = 1u; gen <= m_gen; ++gen) {
Expand Down Expand Up @@ -185,10 +206,10 @@ population ihs::evolve(population pop) const
// we augment the list with the new fitness
fitnesses.push_back(new_f);
// select the best pop.size() individuals
best_idxs = select_best_N_mo(fitnesses, pop.size());
best_idxs = select_best_N_mo(fitnesses, NP);
// define the new population
for (population::size_type i = 0u; i < pop.size(); ++i) {
if (best_idxs[i] == pop.size()) { // this is the new guy
for (population::size_type i = 0u; i < NP; ++i) {
if (best_idxs[i] == NP) { // this is the new guy
pop.set_xf(i, new_x, new_f);
} else { // these were already in the pop somewhere
pop.set_xf(i, pop.get_x()[best_idxs[i]], pop.get_f()[best_idxs[i]]);
Expand Down
21 changes: 21 additions & 0 deletions src/algorithms/maco.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ population maco::evolve(population pop) const
const auto &prob = pop.get_problem();
auto n_x = prob.get_nx();
auto pop_size = pop.size();
auto bounds = prob.get_bounds();
unsigned count_screen = 1u; // regulates the screen output
auto fevals0 = prob.get_fevals(); // discount for the already made fevals
auto n_f = prob.get_nf(); // n_f=prob.get_nobj()+prob.get_nec()+prob.get_nic()
Expand Down Expand Up @@ -148,6 +149,26 @@ population maco::evolve(population pop) const
pagmo_throw(std::invalid_argument, "This is a multiobjective algorithm, while number of objectives detected in "
+ prob.get_name() + " is " + std::to_string(prob.get_nf()));
}
// Verify all decision variables respect the bounds
for (decltype(pop_size) i = 0u; i < pop_size; ++i) {
for (decltype(n_x) j = 0u; j < n_x; ++j) {
double x = pop.get_x()[i][j];
if (std::isnan(x)) {
pagmo_throw(std::invalid_argument, "Individual " + std::to_string(i) + " has a gene " + std::to_string(j)
+ " equal to NaN" + std::to_string(x));
}

if (std::isinf(x)) {
pagmo_throw(std::invalid_argument, "Individual " + std::to_string(i) + " has a gene " + std::to_string(j)
+ " equal to infinity" + std::to_string(x));
}

if (x < bounds.first[j] || x > bounds.second[j]) {
pagmo_throw(std::invalid_argument, "Individual " + std::to_string(i) + " has a gene " + std::to_string(j)
+ " out of bounds: " + std::to_string(x));
}
}
}
// ---------------------------------------------------------------------------------------------------------

// No throws, all valid: we clear the logs
Expand Down
20 changes: 20 additions & 0 deletions src/algorithms/mbh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,26 @@ population mbh::evolve(population pop) const
+ ", while the problem dimension is: " + std::to_string(dim)
+ ". They need to be equal for MBH to work.");
}
// Verify all decision variables respect the bounds
for (decltype(NP) i = 0u; i < NP; ++i) {
for (decltype(dim) j = 0u; j < dim; ++j) {
double x = pop.get_x()[i][j];
if (std::isnan(x)) {
pagmo_throw(std::invalid_argument, "Individual " + std::to_string(i) + " has a gene " + std::to_string(j)
+ " equal to NaN" + std::to_string(x));
}

if (std::isinf(x)) {
pagmo_throw(std::invalid_argument, "Individual " + std::to_string(i) + " has a gene " + std::to_string(j)
+ " equal to infinity" + std::to_string(x));
}

if (x < bounds.first[j] || x > bounds.second[j]) {
pagmo_throw(std::invalid_argument, "Individual " + std::to_string(i) + " has a gene " + std::to_string(j)
+ " out of bounds: " + std::to_string(x));
}
}
}
// ---------------------------------------------------------------------------------------------------------

// No throws, all valid: we clear the logs
Expand Down
Loading
Loading