Distributed NSGA-II

Example

[ ]:
from math import sqrt

from jmetal.core.problem import FloatProblem
from jmetal.core.solution import FloatSolution


class ZDT1Modified(FloatProblem):

    def __init__(self, number_of_variables: int=30):
        """ :param number_of_variables: Number of decision variables of the problem.
        """
        super(ZDT1Modified, self).__init__()
        self.number_of_variables = number_of_variables
        self.number_of_objectives = 2
        self.number_of_constraints = 0

        self.obj_directions = [self.MINIMIZE, self.MINIMIZE]
        self.obj_labels = ['f(x)', 'f(y)']

        self.lower_bound = self.number_of_variables * [0.0]
        self.upper_bound = self.number_of_variables * [1.0]

    def evaluate(self, solution: FloatSolution) -> FloatSolution:
        g = self.__eval_g(solution)
        h = self.__eval_h(solution.variables[0], g)

        solution.objectives[0] = solution.variables[0]
        solution.objectives[1] = h * g

        s: float = 0.0
        for i in range(1000):
            for j in range(1000):
                s += i * 0.235 / 1.234 + 1.23525 * j

        return solution

    def __eval_g(self, solution: FloatSolution):
        g = sum(solution.variables) - solution.variables[0]

        constant = 9.0 / (solution.number_of_variables - 1)
        g = constant * g
        g = g + 1.0

        return g

    def __eval_h(self, f: float, g: float) -> float:
        return 1.0 - sqrt(f / g)

    def get_name(self):
        return 'ZDT1'
[ ]:
from dask.distributed import Client
from distributed import LocalCluster

from jmetal.algorithm.multiobjective.nsgaii import DistributedNSGAII
from jmetal.operator import PolynomialMutation, SBXCrossover
from jmetal.util.termination_criterion import StoppingByEvaluations

# ZDT1 version including a loop for increasing the computing time
#  of the evaluation functions
problem = ZDT1Modified()

# setup Dask client
client = Client(LocalCluster(n_workers=24))

ncores = sum(client.ncores().values())
print(f'{ncores} cores available')

# creates the algorithm
max_evaluations = 25000

algorithm = DistributedNSGAII(
    problem=problem,
    population_size=100,
    mutation=PolynomialMutation(probability=1.0 / problem.number_of_variables, distribution_index=20),
    crossover=SBXCrossover(probability=1.0, distribution_index=20),
    termination_criterion=StoppingByEvaluations(max=max_evaluations),
    number_of_cores=ncores,
    client=client
)

algorithm.run()
solutions = algorithm.get_result()

We can now visualize the Pareto front approximation:

[ ]:
from jmetal.lab.visualization.plotting import Plot
from jmetal.util.solution import get_non_dominated_solutions

front = get_non_dominated_solutions(solutions)

plot_front = Plot(plot_title='Pareto front approximation', axis_labels=['x', 'y'])
plot_front.plot(front, label='Distributed NSGAII-ZDT1')

API

class jmetal.algorithm.multiobjective.nsgaii.DistributedNSGAII(problem: jmetal.core.problem.Problem, population_size: int, mutation: jmetal.core.operator.Mutation, crossover: jmetal.core.operator.Crossover, number_of_cores: int, client, selection: jmetal.core.operator.Selection = <jmetal.operator.selection.BinaryTournamentSelection object>, termination_criterion: jmetal.util.termination_criterion.TerminationCriterion = <jmetal.util.termination_criterion.StoppingByEvaluations object>, dominance_comparator: jmetal.util.comparator.DominanceComparator = <jmetal.util.comparator.DominanceComparator object>)[source]

Bases: jmetal.core.algorithm.Algorithm

create_initial_solutions() → List[S][source]

Creates the initial list of solutions of a metaheuristic.

evaluate(solutions: List[S]) → List[S][source]

Evaluates a solution list.

get_name() → str[source]
get_observable_data() → dict[source]

Get observable data, with the information that will be send to all observers each time.

get_result() → R[source]
init_progress() → None[source]

Initialize the algorithm.

run()[source]

Execute the algorithm.

step() → None[source]

Performs one iteration/step of the algorithm’s loop.

stopping_condition_is_met() → bool[source]

The stopping condition is met or not.

update_progress()[source]

Update the progress after each iteration.