[JAVA] jMetal Explication - Interface du problème

Page originale

https://github.com/jMetal/jMetalDocumentation/blob/master/problem.md

Je viens d'en faire du japonais. Le texte ci-dessous.

The Problem interface

La classe qui exprime le problème implémente l'interface Problem.

package org.uma.jmetal.problem;

/**
 * Interface representing a multi-objective optimization problem
 *
 * @author Antonio J. Nebro <[email protected]>
 *
 * @param <S> Encoding
 */
public interface Problem<S extends Solution<?>> extends Serializable {
  /* Getters */
  public int getNumberOfVariables() ;
  public int getNumberOfObjectives() ;
  public int getNumberOfConstraints() ;
  public String getName() ;

  /* Methods */
  public void evaluate(S solution) ;
  public S createSolution() ;

Les problèmes sont caractérisés par le nombre de déterminants, le nombre de fonctions objectives et le nombre de contraintes. Par conséquent, une méthode getter est définie pour obtenir chaque valeur. Le paramètre virtuel «S» détermine le codage de la solution. ʻEvaluate () est une méthode qui évalue la solution de la classe S, et createSolution () ʻest une méthode qui crée une nouvelle solution.

Comme l'interface Solution est de type générique, jMetal5 a de nombreuses interfaces qui étendent Solution pour représenter des problèmes de valeur continue et des problèmes binaires. Par exemple, l'interface «DoubleProblem» est définie comme suit.

package org.uma.jmetal.problem;

/**
 * Interface representing continuous problems
 *
 * @author Antonio J. Nebro <[email protected]>
 */
public interface DoubleProblem extends Problem<DoubleSolution> {
  Double getLowerBound(int index) ;
  Double getUpperBound(int index) ;
}

Une classe qui implémente «DoubleProblem» n'accepte que «DoubleSolution». Ensuite, il est nécessaire d'implémenter une méthode getter qui acquiert les limites inférieure et supérieure de chaque variable. Dans jMetal5, ʻAbstractDoubleProblem est préparé comme la classe abstraite par défaut qui implémente DoubleProblem`.

package org.uma.jmetal.problem.impl;

public abstract class AbstractDoubleProblem extends AbstractGenericProblem<DoubleSolution>
  implements DoubleProblem {

  private List<Double> lowerLimit ;
  private List<Double> upperLimit ;

  /* Getters */
  @Override
  public Double getUpperBound(int index) {
    return upperLimit.get(index);
  }

  @Override
  public Double getLowerBound(int index) {
    return lowerLimit.get(index);
  }

  /* Setters */
  protected void setLowerLimit(List<Double> lowerLimit) {
    this.lowerLimit = lowerLimit;
  }

  protected void setUpperLimit(List<Double> upperLimit) {
    this.upperLimit = upperLimit;
  }

  @Override
  public DoubleSolution createSolution() {
    return new DefaultDoubleSolution(this)  ;
  }
}

Comme exemple du problème de la valeur continue, [Kursawa](https://github.com/jMetal/jMetal/blob/jmetal-5.0/jmetal-problem/src/main/java/org/uma/jmetal /problem/multiobjective/Kursawe.java) Le problème est implémenté.

package org.uma.jmetal.problem.multiobjective;

/**
 * Class representing problem Kursawe
 */
public class Kursawe extends AbstractDoubleProblem {

  /**
   * Constructor.
   * Creates a default instance of the Kursawe problem.
   */
  public Kursawe() {
    // 3 variables by default
    this(3);
  }

  /**
   * Constructor.
   * Creates a new instance of the Kursawe problem.
   *
   * @param numberOfVariables Number of variables of the problem
   */
  public Kursawe(Integer numberOfVariables) {
    setNumberOfVariables(numberOfVariables);
    setNumberOfObjectives(2);
    setName("Kursawe");

    List<Double> lowerLimit = new ArrayList<>(getNumberOfVariables()) ;
    List<Double> upperLimit = new ArrayList<>(getNumberOfVariables()) ;

    for (int i = 0; i < getNumberOfVariables(); i++) {
      lowerLimit.add(-5.0);
      upperLimit.add(5.0);
    }

    setLowerLimit(lowerLimit);
    setUpperLimit(upperLimit);
  }

  /** Evaluate() method */
  public void evaluate(DoubleSolution solution){
    double aux, xi, xj;
    double[] fx = new double[getNumberOfObjectives()];
    double[] x = new double[getNumberOfVariables()];
    for (int i = 0; i < solution.getNumberOfVariables(); i++) {
      x[i] = solution.getVariableValue(i) ;
    }

    fx[0] = 0.0;
    for (int var = 0; var < solution.getNumberOfVariables() - 1; var++) {
      xi = x[var] * x[var];
      xj = x[var + 1] * x[var + 1];
      aux = (-0.2) * Math.sqrt(xi + xj);
      fx[0] += (-10.0) * Math.exp(aux);
    }

    fx[1] = 0.0;

    for (int var = 0; var < solution.getNumberOfVariables(); var++) {
      fx[1] += Math.pow(Math.abs(x[var]), 0.8) +
        5.0 * Math.sin(Math.pow(x[var], 3.0));
    }

    solution.setObjective(0, fx[0]);
    solution.setObjective(1, fx[1]);
  }
}

Comme l'interface DoubleProblem et le AbstractDoubleProblem, BinaryProblem et ʻAbstractBinaryProblem, ʻInteger Problem et ʻAbstract Integer Problem` sont définis.

Problème contraint

Il existe deux façons de gérer les problèmes contraints avec jMetal5.

  1. Gérez les violations de contraintes dans la méthode ʻevaluate () `.
  2. Implémentez l'interface ConstrainedProblem avec une méthode pour évaluer les contraintes.
package org.uma.jmetal.problem;

/**
 * Interface representing problems having constraints
 *
 * @author Antonio J. Nebro <[email protected]>
 */
public interface ConstrainedProblem<S extends Solution<?>> extends Problem<S> {

 /* Getters */
  public int getNumberOfConstraints() ;
	
  /* Methods */
  public void evaluateConstraints(S solution) ;
}

jMetal5 adopte généralement cette dernière approche. A titre d'exemple, voici un problème Tanaka avec deux contraintes.

package org.uma.jmetal.problem.multiobjective;

/**
 * Class representing problem Tanaka
 */
public class Tanaka extends AbstractDoubleProblem implements ConstrainedProblem<DoubleSolution> {
  public OverallConstraintViolation<DoubleSolution> overallConstraintViolationDegree ;
  public NumberOfViolatedConstraints<DoubleSolution> numberOfViolatedConstraints ;

  /**
   * Constructor.
   * Creates a default instance of the problem Tanaka
   */
  public Tanaka() {
    setNumberOfVariables(2);
    setNumberOfObjectives(2);
    setNumberOfConstraints(2);
    setName("Tanaka") ;

    List<Double> lowerLimit = new ArrayList<>(getNumberOfVariables()) ;
    List<Double> upperLimit = new ArrayList<>(getNumberOfVariables()) ;

    for (int i = 0; i < getNumberOfVariables(); i++) {
      lowerLimit.add(10e-5);
      upperLimit.add(Math.PI);
    }

    setLowerLimit(lowerLimit);
    setUpperLimit(upperLimit);

    overallConstraintViolationDegree = new OverallConstraintViolation<DoubleSolution>() ;
    numberOfViolatedConstraints = new NumberOfViolatedConstraints<DoubleSolution>() ;
  }

  @Override
  public void evaluate(DoubleSolution solution)  {
    solution.setObjective(0, solution.getVariableValue(0));
    solution.setObjective(1, solution.getVariableValue(1));
  }

  /** EvaluateConstraints() method */
  @Override
  public void evaluateConstraints(DoubleSolution solution)  {
    double[] constraint = new double[this.getNumberOfConstraints()];

    double x1 = solution.getVariableValue(0) ;
    double x2 = solution.getVariableValue(1) ;

    constraint[0] = (x1 * x1 + x2 * x2 - 1.0 - 0.1 * Math.cos(16.0 * Math.atan(x1 / x2)));
    constraint[1] = -2.0 * ((x1 - 0.5) * (x1 - 0.5) + (x2 - 0.5) * (x2 - 0.5) - 0.5);

    double overallConstraintViolation = 0.0;
    int violatedConstraints = 0;
    for (int i = 0; i < getNumberOfConstraints(); i++) {
      if (constraint[i]<0.0){
        overallConstraintViolation+=constraint[i];
        violatedConstraints++;
      }
    }

    overallConstraintViolationDegree.setAttribute(solution, overallConstraintViolation);
    numberOfViolatedConstraints.setAttribute(solution, violatedConstraints);
  }
}

Discusion Incorporer l'interface ConstrainedProblem Motivé par le fait que dans les versions précédentes, tous les problèmes avaient ʻevaluate () et ʻevaluateConstraints (). Pour les problèmes sans contrainte, ʻevaluateConstraints () `a été implémenté comme une méthode de. Afin d'éviter les violations du principe de séparation des interfaces, jMetal5 évalue les contraintes uniquement pour les problèmes qui nécessitent des contraintes.

Dans le jMetal original, il était nécessaire d'évaluer la solution deux fois comme suit.

Problem problem ;
Solution solution ;
...
problem.evaluate(solution) ;
problem.evaluateContraints(solution) ;

La version actuelle doit inclure une vérification des restrictions.

Problem problem ;
Solution solution ;
...
problem.evaluate(solution) ;
problem.evaluateContraints(solution) ;

Recommended Posts

jMetal Explication - Interface du problème
jMetal Explication - Interface de solution
jMetal Explanation - Interface de l'algorithme
interface
Interface Essayez de créer un problème Java TypeScript 7-3