Decompose

class pagmo::decompose

Decompose meta-problem.

../../_images/decompose.png

This meta-problem decomposes a multi-objective input problem (user-defined or a pagmo::problem), resulting in a single-objective pagmo::problem with a fitness function combining the original fitness functions. In particular, three different decomposition methods are here made available:

  • weighted decomposition
  • Tchebycheff decomposition
  • boundary interception method (with penalty constraint)

In the case of \(n\) objectives, we indicate with: \( \mathbf f(\mathbf x) = [f_1(\mathbf x), \ldots, f_n(\mathbf x)] \) the vector containing the original multiple objectives, with: \( \boldsymbol \lambda = (\lambda_1, \ldots, \lambda_n) \) a \(n\)-dimensional weight vector and with: \( \mathbf z^* = (z^*_1, \ldots, z^*_n) \) a- \(n\) dimensional reference point. We also ussume \(\lambda_i > 0, \forall i=1..n\) and \(\sum_i \lambda_i = 1\)

The decomposed problem is thus a single objective optimization problem having the following single objective, according to the decomposition method chosen:

  • weighted decomposition: \( f_d(\mathbf x) = \boldsymbol \lambda \cdot \mathbf f \)
  • Tchebycheff decomposition: \( f_d(\mathbf x) = \max_{1 \leq i \leq m} \lambda_i \vert f_i(\mathbf x) - z^*_i \vert \)
  • boundary interception method (with penalty constraint): \( f_d(\mathbf x) = d_1 + \theta d_2\)

where \(d_1 = (\mathbf f - \mathbf z^*) \cdot \hat {\mathbf i}_{\lambda}\), \(d_2 = \vert (\mathbf f - \mathbf z^*) - d_1 \hat {\mathbf i}_{\lambda})\vert\) and \( \hat {\mathbf i}_{\lambda} = \frac{\boldsymbol \lambda}{\vert \boldsymbol \lambda \vert}\)

Note
The reference point \(z^*\) is often taken as the ideal point and as such it may be allowed to change during the course of the optimization / evolution. The argument adapt_ideal activates this behaviour so that whenever a new ideal point is found \(z^*\) is adapted accordingly.
Note
The use of pagmo::decompose discards gradients and hessians so that if the original user defined problem implements them, they will not be available in the decomposed problem. The reason for this behaviour is that the Tchebycheff decomposition is not differentiable. Also, the use of this class was originally intended for derivative-free optimization.
See
“Q. Zhang – MOEA/D: A Multiobjective Evolutionary Algorithm Based on Decomposition”
See
https://en.wikipedia.org/wiki/Multi-objective_optimization#Scalarizing_multi-objective_optimization_problems

Inherits from pagmo::problem

Public Functions

template <typename T>
decompose(T &&p, const vector_double &weight, const vector_double &z, const std::string &method = "weighted", bool adapt_ideal = false)

Constructor from problem.

Wraps a user-defined problem so that its fitness will be decomposed using one of three decomposition methods. pagmo::translate objects can be used as user-defined problems in the construction of a pagmo::problem.

Template Parameters
Parameters
  • p -

    The input problem.

  • method -

    an std::string containing the decomposition method chosen

  • weight -

    the vector of weights \(\boldsymbol \lambda\)

  • z -

    the reference point \(\mathbf z^*\)

  • adapt_ideal -

    when true the reference point is adapted at each fitness evaluation to be the ideal point

Exceptions
  • std::invalid_argument -

    if the problem of type T is single objective

  • std::invalid_argument -

    if the problem of type T is constrained

  • std::invalid_argument -

    if method is not one of [“weighted”, “tchebycheff” or “bi”]

  • std::invalid_argument -

    if weight is not of size \(n\)

  • std::invalid_argument -

    if z is not of size \(n\)

  • std::invalid_argument -

    if weight is not such that \(\lambda_i > 0, \forall i=1..n\)

  • std::invalid_argument -

    if weight is not such that \(\sum_i \lambda_i = 1\)

vector_double fitness(const vector_double &x) const

Fitness of the decomposed problem.

vector_double::size_type get_nobj() const

A decomposed problem has one objective.

sparsity_pattern gradient_sparsity() const

Returns a dense gradient_sparsity for the decomposed problem.

std::vector<sparsity_pattern> hessians_sparsity() const

Returns a dense hessians_sparsity for the decomposed problem.

vector_double get_z() const

Gets the current reference point (may be different from the one the object was constructed with)

std::string get_name() const

Appends “[decomposed]” to the user-defined problem name.

std::string get_extra_info() const

Extra informations.

template <typename Archive>
void serialize(Archive &ar)

Serialize.

template <typename T>
const T *extract() const

Extracts the user-defined problem.

Extracts the original problem that was provided by the user, thus granting access to additional resources there implemented.

Return
a const pointer to the user-defined problem, or nullptr if T does not correspond exactly to the original problem type used in the constructor.
Template Parameters
  • T -

    The type of the orignal user-defined problem

std::pair<vector_double, vector_double> get_bounds() const

Box-bounds.

Return
Returns \( (\mathbf{lb}, \mathbf{ub}) \), the box-bounds as returned by the corresponding user-implemented method

vector_double::size_type get_nec() const

Number of equality constraints.

Return
Returns \( n_{ec} \), the number of inequality constraints as returned by the the corresponding user-implemented method if present, zero otherwise

vector_double::size_type get_nic() const

Number of inequality constraints.

Return
Returns \( n_{ic} \), the number of inequality constraints as returned by the the corresponding user-implemented method if present, zero otherwise

void set_seed(unsigned int seed)

Sets the seed for the stochastic variables.

Sets the seed to be used in the fitness function to instantiate all stochastic variables.

Parameters
  • seed -

    seed

bool has_set_seed() const

Check if the user-defined problem implements a set_seed method.

If the user defined problem implements a set_seed method, this will return true, false otherwise. The value returned can also be forced by the user by implementing the additional method

bool has_set_seed() const

in the user-defined problem

Return
a boolean flag