Source code for jmetal.problem.multiobjective.fda

from abc import ABC, abstractmethod
from math import cos, floor, pi, pow, sin, sqrt

import numpy

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

"""
.. module:: FDA
   :platform: Unix, Windows
   :synopsis: FDA problem family of dynamic multi-objective problems.

.. moduleauthor:: Antonio J. Nebro <antonio@lcc.uma.es>
"""


[docs] class FDA(DynamicProblem, FloatProblem, ABC): def __init__(self): super(FDA, self).__init__() self.tau_T = 5 self.nT = 10 self.time = 1.0 self.problem_modified = False
[docs] def update(self, *args, **kwargs): counter: int = kwargs["COUNTER"] self.time = (1.0 / self.nT) * floor(counter * 1.0 / self.tau_T) self.problem_modified = True
[docs] def the_problem_has_changed(self) -> bool: return self.problem_modified
[docs] def clear_changed(self) -> None: self.problem_modified = False
[docs] @abstractmethod def evaluate(self, solution: FloatSolution): pass
[docs] class FDA1(FDA): """Problem FDA1. .. note:: Bi-objective dynamic unconstrained problem. The default number of variables is 100. """ def __init__(self, number_of_variables: int = 100): """:param number_of_variables: Number of decision variables of the problem.""" super(FDA1, 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 * [-1.0] self.upper_bound = self.number_of_variables * [1.0] self.lower_bound[0] = 0.0 self.upper_bound[0] = 1.0
[docs] 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 return solution
def __eval_g(self, solution: FloatSolution): gT = sin(0.5 * pi * self.time) g = 1.0 + sum([pow(v - gT, 2) for v in solution.variables[1:]]) return g def __eval_h(self, f: float, g: float) -> float: return 1.0 - sqrt(f / g)
[docs] def get_name(self): return "FDA1"
[docs] class FDA2(FDA): """Problem FDA2 .. note:: Bi-objective dynamic unconstrained problem. The default number of variables is 31. """ def __init__(self, number_of_variables: int = 31): """:param number_of_variables: Number of decision variables of the problem.""" super(FDA2, 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 * [-1.0] self.upper_bound = self.number_of_variables * [1.0] self.lower_bound[0] = 0.0 self.upper_bound[0] = 1.0
[docs] def evaluate(self, solution: FloatSolution) -> FloatSolution: g = self.__eval_g(solution, 1, len(solution.variables)) h = self.__eval_h(solution.variables[0], g) solution.objectives[0] = solution.variables[0] solution.objectives[1] = h * g return solution
def __eval_g(self, solution: FloatSolution, lower_limit: int, upper_limit: int): g = sum([pow(v, 2) for v in solution.variables[lower_limit:upper_limit]]) g += 1.0 + sum([pow(v + 1.0, 2.0) for v in solution.variables[upper_limit:]]) return g def __eval_h(self, f: float, g: float) -> float: ht = 0.2 + 4.8 * pow(self.time, 2.0) return 1.0 - pow(f / g, ht)
[docs] def get_name(self): return "FDA2"
[docs] class FDA3(FDA): """Problem FDA3 .. note:: Bi-objective dynamic unconstrained problem. The default number of variables is 30. """ def __init__(self, number_of_variables: int = 30): """:param number_of_variables: Number of decision variables of the problem.""" super(FDA3, self).__init__() self.number_of_variables = number_of_variables self.number_of_objectives = 2 self.number_of_constraints = 0 self.limitInfI = 0 self.limitSupI = 1 self.limitInfII = 1 self.obj_directions = [self.MINIMIZE, self.MINIMIZE] self.obj_labels = ["f(x)", "f(y)"] self.lower_bound = self.number_of_variables * [-1.0] self.upper_bound = self.number_of_variables * [1.0] self.lower_bound[0] = 0.0 self.upper_bound[0] = 1.0
[docs] def evaluate(self, solution: FloatSolution) -> FloatSolution: g = self.__eval_g(solution, self.limitInfII) h = self.__eval_h(solution.variables[0], g) solution.objectives[0] = self.__eval_f(solution, self.limitInfI, self.limitSupI) solution.objectives[1] = g * h return solution
def __eval_f(self, solution: FloatSolution, lower_limit: int, upper_limit: int): f = 0.0 aux = 2.0 * sin(0.5 * pi * self.time) ft = pow(10, aux) f += sum([pow(v, ft) for v in solution.variables[lower_limit:upper_limit]]) return f def __eval_g(self, solution: FloatSolution, lower_limit: int): gt = abs(sin(0.5 * pi * self.time)) g = sum([pow(v - gt, 2) for v in solution.variables[lower_limit:]]) g = g + 1.0 + gt return g def __eval_h(self, f: float, g: float) -> float: h = 1.0 - sqrt(f / g) return h
[docs] def get_name(self): return "FDA3"
[docs] class FDA4(FDA): """Problem FDA4 .. note:: Three-objective dynamic unconstrained problem. The default number of variables is 12. """ M = 3 def __init__(self, number_of_variables: int = 12): """:param number_of_variables: Number of decision variables of the problem.""" super(FDA4, self).__init__() self.number_of_variables = number_of_variables self.number_of_objectives = 3 self.number_of_constraints = 0 self.obj_directions = [self.MINIMIZE, self.MINIMIZE] self.obj_labels = ["f(x)", "f(y)", "f(z)"] self.lower_bound = self.number_of_variables * [0.0] self.upper_bound = self.number_of_variables * [1.0]
[docs] def evaluate(self, solution: FloatSolution) -> FloatSolution: g = self.__eval_g(solution, self.M - 1) solution.objectives[0] = self.__eval_f1(solution, g) solution.objectives[1] = self.__eval_fk(solution, g, 2) solution.objectives[2] = self.__eval_fm(solution, g) return solution
def __eval_g(self, solution: FloatSolution, lower_limit: int): gt = abs(sin(0.5 * pi * self.time)) g = sum([pow(v - gt, 2) for v in solution.variables[lower_limit:]]) return g def __eval_f1(self, solution: FloatSolution, g: float) -> float: f = 1.0 + g mult = numpy.prod([cos(v * pi / 2.0) for v in solution.variables[: self.M - 1]]) return f * mult def __eval_fk(self, solution: FloatSolution, g: float, k: int) -> float: f = 1.0 + g aux = sin((solution.variables[self.M - k] * pi) / 2.0) mult = numpy.prod([cos(v * pi / 2.0) for v in solution.variables[: self.M - k]]) return f * mult * aux def __eval_fm(self, solution: FloatSolution, g: float) -> float: fm = 1.0 + g fm *= sin((solution.variables[0] * pi) / 2.0) return fm
[docs] def get_name(self): return "FDA4"
[docs] class FDA5(FDA): """Problem FDA5 .. note:: Three-objective dynamic unconstrained problem. The default number of variables is 12. """ M = 3 def __init__(self, number_of_variables: int = 12): """:param number_of_variables: Number of decision variables of the problem.""" super(FDA5, self).__init__() self.number_of_variables = number_of_variables self.number_of_objectives = 3 self.number_of_constraints = 0 self.obj_directions = [self.MINIMIZE, self.MINIMIZE] self.obj_labels = ["f(x)", "f(y)", "f(z)"] self.lower_bound = self.number_of_variables * [0.0] self.upper_bound = self.number_of_variables * [1.0]
[docs] def evaluate(self, solution: FloatSolution) -> FloatSolution: g = self.__eval_g(solution, self.M - 1) ft = 1.0 + 100.0 * pow(sin(0.5 * pi * self.time), 4.0) solution.objectives[0] = self.__eval_f1(solution, g, ft) solution.objectives[1] = self.__eval_fk(solution, g, 2, ft) solution.objectives[2] = self.__eval_fm(solution, g, ft) return solution
def __eval_g(self, solution: FloatSolution, lower_limit: int): gt = abs(sin(0.5 * pi * self.time)) g = sum([pow(v - gt, 2) for v in solution.variables[lower_limit:]]) return g def __eval_f1(self, solution: FloatSolution, g: float, ft: float) -> float: f = 1.0 + g mult = numpy.prod([cos(pow(v, ft) * pi / 2.0) for v in solution.variables[: self.M - 1]]) return f * mult def __eval_fk(self, solution: FloatSolution, g: float, k: int, ft: float) -> float: f = 1.0 + g mult = numpy.prod([cos(pow(v, ft) * pi / 2.0) for v in solution.variables[: self.M - k]]) yy = pow(solution.variables[self.M - k], ft) mult *= sin(yy * pi / 2.0) return f * mult def __eval_fm(self, solution: FloatSolution, g: float, ft: float) -> float: fm = 1.0 + g y_1 = pow(solution.variables[0], ft) mult = sin(y_1 * pi / 2.0) return fm * mult
[docs] def get_name(self): return "FDA5"