Coding a User Defined Problem with multiple objectives#

In this chapter we show how to code an unconstrained user defined problem (UDP) with multiple objectives. We assume that the mathematical formulation of problem is the following:

\[\begin{split}\begin{array}{ll} \mbox{minimize: } & f_{1}(x) = x^{2} \\ & f_{2}(x) = (x-2)^{2} \\ \mbox{subject to:} & 0 \le x \le 2 \end{array}\end{split}\]

which is a test function for multi-objective optimization being introduced in Schaffer, J. David (1984). Some experiments in machine learning using vector evaluated genetic algorithms (artificial intelligence, optimization, adaptation, pattern recognition) (PhD). Vanderbilt University. and illustrated here.

The implementation as UDP can be realized as follows:

>>> class Schaffer:
...     # Define objectives
...     def fitness(self, x):
...         f1 = x[0]**2
...         f2 = (x[0]-2)**2
...         return [f1, f2]
...
...     # Return number of objectives
...     def get_nobj(self):
...         return 2
...
...     # Return bounds of decision variables
...     def get_bounds(self):
...         return ([0]*1, [2]*1)
...
...     # Return function name
...     def get_name(self):
...         return "Schaffer function N.1"

Note that the only difference between a mono- and multi-objective problem lies in the number of objectives.

Let’s now create an object from our new UDP class and pass it to a pygmo problem.

>>> import pygmo as pg
>>> # create UDP
>>> prob = pg.problem(Schaffer())

In the next step, the problem can be solved straightforward using the NSGA2 algorithm from the algorithm class:

>>> # create population
>>> pop = pg.population(prob, size=20)
>>> # select algorithm
>>> algo = pg.algorithm(pg.nsga2(gen=40))
>>> # run optimization
>>> pop = algo.evolve(pop)
>>> # extract results
>>> fits, vectors = pop.get_f(), pop.get_x()
>>> # extract and print non-dominated fronts
>>> ndf, dl, dc, ndr = pg.fast_non_dominated_sorting(fits)
>>> print(ndf) 
[array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19], dtype=uint64)]

And we are already done!