[BUG] solutions violating the bounds are declared feasible
- Dominant language
- C++
- Stars
- 536
- Forks
- 74
- PR merge metrics
- No merged PRs in 30d
Description
**Describe the bug**
The feasibility_x method returns True for solutions that clearly violate the declared bounds. On the other hand, if I explicitly add constraints for the bounds (within the fitness method) the feasibility_x method works as expected. I do not know if this is an intended behaviour but it seems to be contradictory to me.
**To Reproduce**
I adapted the code from one of the tutorials to reproduce this behaviour. In the example that follows, bounds are declared using the get_bounds method and no errors are generated for solutions that violate the bounds.
```
import pygmo as pg
class sphere_function:
def __init__(self, dim):
self.dim = dim
def fitness(self, x):
return [sum(x*x)]
def get_bounds(self):
return ([-1] * self.dim, [1] * self.dim)
def get_name(self):
return "Sphere Function"
def get_extra_info(self):
return "\tDimensions: " + str(self.dim)
prob_dim = 3
pop_size = 10
prob = pg.problem(sphere_function(prob_dim))
algo = pg.algorithm(pg.bee_colony(gen = 20, limit = 20))
pop = pg.population(prob, pop_size)
pop = algo.evolve(pop)
# create solution not violating the bounds
new_solution = [1 for i in range(prob_dim)]
# it is considered feasible
assert prob.feasibility_x(new_solution)
# create another solution not violating the bounds
new_solution2 = [-1 for i in range(prob_dim)]
# it is considered feasible
assert prob.feasibility_x(new_solution2)
# create solution clearly violating the bounds
new_solution = [2 for i in range(prob_dim)]
# it is considered feasible
assert prob.feasibility_x(new_solution)
# create another solution clearly violating the bounds
new_solution2 = [-2 for i in range(prob_dim)]
# it is considered feasible
assert prob.feasibility_x(new_solution2)
# add the solutions to the population
pop.push_back(new_solution)
pop.push_back(new_solution2)
# obtain solutions from the population
x_pool = pop.get_x()
# they are considered feasible
assert prob.feasibility_x(x_pool[pop_size])
assert prob.feasibility_x(x_pool[pop_size+1])
```
If I add constraints to the fitness method, the feasibility_x returns the expected result (solutions that violate the bounds are infeasible).
```
import pygmo as pg
class sphere_function2:
def __init__(self, dim):
self.dim = dim
def get_bounds(self):
return ([-1] * self.dim, [1] * self.dim)
def get_name(self):
return "Sphere Function"
def get_extra_info(self):
return "\tDimensions: " + str(self.dim)
# inequality constraints
def get_nic(self):
return 2*self.dim
# fitness with constraints for the bounds
def fitness(self, x):
#
obj = sum(x*x)
# upper bound
ineq_ub = [x[i]-1 for i in range(self.dim)]
# lowe bound
ineq_lb = [-x[i]-1 for i in range(self.dim)]
return [obj, *ineq_ub, *ineq_lb]
prob_dim = 3
pop_size = 10
prob = pg.problem(sphere_function2(prob_dim))
algo = pg.algorithm(pg.ihs(gen=20))
pop = pg.population(prob, pop_size)
pop = algo.evolve(pop)
# create solution not violating the bounds
new_solution = [1 for i in range(prob_dim)]
# it is considered feasible
assert prob.feasibility_x(new_solution)
# create another solution not violating the bounds
new_solution2 = [-1 for i in range(prob_dim)]
# it is considered feasible
assert prob.feasibility_x(new_solution2)
# create solution clearly violating the bounds
new_solution = [2 for i in range(prob_dim)]
# it is not considered feasible
assert not prob.feasibility_x(new_solution)
# create another solution clearly violating the bounds
new_solution2 = [-2 for i in range(prob_dim)]
# it is not considered feasible
assert not prob.feasibility_x(new_solution2)
# add the solutions to the population
pop.push_back(new_solution)
pop.push_back(new_solution2)
# obtain solutions from the population
x_pool = pop.get_x()
# they are not considered feasible
assert not prob.feasibility_x(x_pool[pop_size])
assert not prob.feasibility_x(x_pool[pop_size+1])
```
**Expected behavior**
I expected the feasibility_x method to return False for solutions that clearly violate the bounds. It does not seem to do at the moment, only when constraints are added explicitly.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Environment (please complete the following information):**
- OS: Ubuntu 22.04
- Installation method: compiled from source
- Version: 2.19.6
**Additional context**
The problem formulated in the paper does not include the bounds in the constraints section, so maybe this behaviour is intended.
Contributor guide
No contributing guide indexed for this repository
Research direction
The report exercises pg.problem.feasibility_x(), get_bounds(), fitness(), and population.push_back() through Python examples; start by reproducing the assertions on version 2.19.6 and tracing how feasibility_x interprets bounds versus inequality constraints. Done means the intended bounds semantics are established and the issue is resolved or clearly documented.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp, python
- Domain
- api
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100