Pygmo multi-objective optimization with constraints

146 views Asked by At

I want to solve a multi-objective optimization problem with constraints using pygmo and obtain the resulting Pareto front. However, even though my program only contains linear constraints, I obtain an error:

what: Non linear constraints detected in <class '__main__.SimpleProblem'> instance. NSGA-II: cannot deal with them.

I implemented a more simple program to recreate the error:

import pygmo as pg

class SimpleProblem:

    # objective functions and constraints
    def fitness(self, x):

        fitness_vector = []
        # first objective
        fitness_vector.append(x[0])
        constants = [1,0.5,0.5]
        # second objective
        fitness_vector.append(-sum([x[i] * constants[i] for i in range(3)]))
        # constraint
        fitness_vector.append(sum([x[i] for i in range(3)]) -2)

        return fitness_vector

    # number of objectives
    def get_nobj(self):
        return 2
    
    # number of inequality constraints
    def get_nic(self):
        return 1

    # real dimension of the problem
    def get_ncx(self):
        return 1

    # integer dimension of the problem
    def get_nix(self):
        return 3
    
    # bounds of the decision variables
    def get_bounds(self):
        return ([0] + [0] * 3, [1e6] + [1] * 3)


if __name__ == "__main__":
    model = SimpleProblem()
    problem = pg.problem(model)
    algorithm = pg.algorithm(pg.nsga2(gen=1000))
    population = pg.population(problem, size=100)
    population = algorithm.evolve(population)

which results in the same error. If I remove the constraint it works fine.

To my understanding, fitness should return a vector containing the objectives followed by the constraints, as shown in the example "Coding a User Defined Problem with constraints" of the pygmo2 documentation. They however do not list an example with multiple objectives that contains other constraints except the decision variable bounds. Do I need to handle the fitness function differently in this case?

I am using pygmo==2.19.5.

1

There are 1 answers

0
Mathieu Bouchard On

Pygmo's NSGA-II implementation doesn't directly support constraints which is why it results in an error.

What you want to do is use pygmo.unconstrain with one of the following available methods:

  • Death penalty: simply penalizes all objectives by the same high value if the fitness vector is infeasible.
  • Kuri’s death penalty: defined by Angel Kuri Morales et al., penalizes all objectives according to the rate of satisfied constraints.
  • Weighted violations penalty: penalizes all objectives by the weighted sum of the constraint violations.
  • Ignore the constraints: simply ignores the constraints.
  • Ignore the objectives: ignores the objectives and defines as a new single objective the overall constraints violation (i.e. the sum of the L2 norms of the equalities and inequalities violations)

pygmo.unconstrain is a meta-problem, so you decorate your problem like this:

problem = pg.unconstrain(pg.problem(model), method='kuri')

Individuals which violate the constraints will be penalized, just like you'd expect.