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

[BUG] solutions violating the bounds are declared feasible #171

Open
thisandthatuser opened this issue Aug 27, 2024 · 1 comment
Open

[BUG] solutions violating the bounds are declared feasible #171

thisandthatuser opened this issue Aug 27, 2024 · 1 comment
Labels
bug Something isn't working

Comments

@thisandthatuser
Copy link
Contributor

thisandthatuser commented Aug 27, 2024

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.

@thisandthatuser thisandthatuser added the bug Something isn't working label Aug 27, 2024
@thisandthatuser thisandthatuser changed the title [BUG] solutions clearly violating the bounds are declared feasible [BUG] solutions violating the bounds are declared feasible Aug 27, 2024
@bluescarni
Copy link
Member

Hi @thisandthatuser !

I was looking at the code for the feasibility_x() method, and it does not seem to me like the notion of box bounds is considered at all when computing the feasibility of a decision vector. I think the method was never intended to check for box bounds, but probably we should ask @darioizzo as I think he wrote that specific piece of code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants