[JAVA] jMetal Explication - Interface de solution

Page originale

https://github.com/jMetal/jMetalDocumentation/blob/master/solution.md Je ne fais que traduire cela grossièrement. Le texte ci-dessous.

Solution interface Lors de l'utilisation de la méta-huristique, nous devons d'abord définir comment exprimer et encoder la solution du problème à résoudre. L'expression de la solution dépend fortement du problème et les opérations applicables (par exemple, recombinaison avec d'autres solutions, procédure de recherche locale, etc.) sont déterminées par l'expression. Par conséquent, le choix de la méthode d'expression de la solution a une grande influence sur le comportement de la métahéristique et, par extension, sur la qualité des résultats obtenus.

La figure ci-dessous montre les classes de base utilisées pour représenter une solution dans jMetal 5.

jMetal_Solution_Class

Cette figure contient trois expressions de solution: binaire, double et entier. Cette approche fournit de nombreuses implémentations pour le même codage et offre une plus grande flexibilité. En outre, en utilisant des génériques, une affectation de valeur de variable incorrecte peut être trouvée dans une erreur de compilation. Par exemple, si vous essayez d'affecter la valeur de «DoubleSolution» à une variable int, une erreur se produira.

Le code de l'interface «Solution» est le suivant.

package org.uma.jmetal.solution;

public interface Solution<T> extends Serializable {
  public void setObjective(int index, double value) ;
  public double getObjective(int index) ;

  public T getVariableValue(int index) ;
  public void setVariableValue(int index, T value) ;
  public String getVariableValueString(int index) ;

  public int getNumberOfVariables() ;
  public int getNumberOfObjectives() ;

  public Solution<T> copy() ;

  public void setAttribute(Object id, Object value) ;
  public Object getAttribute(Object id) ;
}

Solution a une méthode pour accéder aux variables et aux fonctions d'objectif, une méthode de copie et une méthode pour accéder aux attributs.

Defining encodings Un codage spécifique est défini par l'implémentation ou l'extension de l'interface «Solution». L'interface pour une solution avec une liste de variables Double et Integer est définie comme suit:

package org.uma.jmetal.solution;

public interface DoubleSolution extends Solution<Double> {
  public Double getLowerBound(int index) ;
  public Double getUpperBound(int index) ;
}
package org.uma.jmetal.solution;

public interface IntegerSolution extends Solution<Integer> {
  public Integer getLowerBound(int index) ;
  public Integer getUpperBound(int index) ;
}

Ces interfaces fournissent des méthodes pour obtenir les limites inférieure et supérieure des variables Double et Intefer. La méthode de définition de ces valeurs est laissée à la classe d'implémentation.

Dans le cas de «BinarySolution», c'est comme suit.

import org.uma.jmetal.util.binarySet.BinarySet;

public interface BinarySolution extends Solution<BinarySet> {
  public int getNumberOfBits(int index) ;
  public int getTotalNumberOfBits() ;
}

On suppose qu'il représente une liste de variables binaires.

Vous permet de définir des encodages avec des variables mixtes. Par exemple, l'interface suivante définit une solution qui consiste en une liste de valeurs doubles et entières.

package org.uma.jmetal.solution;

public interface IntegerDoubleSolution extends Solution<Number> {
  public Number getLowerBound(int index) ;
  public Number getUpperBound(int index) ;
  public int getNumberOfIntegerVariables() ;
  public int getNumberOfDoubleVariables() ;
}

Implementing solutions Nous avons défini des interfaces pour différentes solutions. Ce qui suit fournit des implémentations par défaut pour tous. Commençons par une classe abstraite appelée ʻAbstractGenericSolution`.

package org.uma.jmetal.solution.impl;

public abstract class AbstractGenericSolution<T, P extends Problem<?>> implements Solution<T> {
  private double[] objectives;
  private List<T> variables;
  protected P problem ;
  protected double overallConstraintViolationDegree ;
  protected int numberOfViolatedConstraints ;
  protected Map<Object, Object> attributes ;
  protected final JMetalRandom randomGenerator ;

ʻAbstractGenericSolution contient toutes les méthodes de Solution. Cette classe est une superclasse de toutes les implémentations Solution de jMetal5. (DefaultBinarySolution, DefaultIntegerSolution, DefaultDoubleSolution, DefaultIntegerDoubleSolution, DefaultIntegerPermutationSolution, DefaultDoubleBinarySolution` .)

Where are the populations? Il n'y a pas de classe qui exprime la population dans jMetal5. Au lieu de cela, «List » est utilisé comme population.

Exemple:

/* A population of double solutions */
List<DoubleSolution> doublePopulation ;

/* The same population using the generic interface */
List<Solution<Double>> doublePopulation ;

/* A population of binary solutions */
List<BinarySolucion> binaryPopulation ;

La classe utilitaire SolutionListUtils fournit un ensemble d'opérations pour List <Solution>. (Par exemple, trouver le meilleur / le pire individu, choisir au hasard une solution, etc.)

Solution attributes En incorporant des attributs, vous pouvez ajouter des champs spécifiques à la solution qui sont nécessaires à certains algorithmes. Par exemple, dans SPEA2, la même adaptabilité est attribuée à la solution, mais dans NSGA-II, il est nécessaire de classer la solution et d'attribuer la valeur de la distance d'encombrement.

Les attributs peuvent être manipulés directement, mais les interfaces suivantes sont également définies.

package org.uma.jmetal.util.solutionattribute;
/**
 * Attributes allows to extend the {@link Solution} classes to incorporate data required by
 * operators or algorithms manipulating them.
 *
 * @author Antonio J. Nebro <[email protected]>
 */
public interface SolutionAttribute <S extends Solution<?>, V> {
  public void setAttribute(S solution, V value) ;
  public V getAttribute(S solution) ;
  public Object getAttributeID() ;
}

L'implémentation par défaut est la suivante.

package org.uma.jmetal.util.solutionattribute.impl;

public class GenericSolutionAttribute <S extends Solution<?>, V> implements SolutionAttribute<S, V>{

  @SuppressWarnings("unchecked")
  @Override
  public V getAttribute(S solution) {
    return (V)solution.getAttribute(getAttributeID());
  }

  @Override
  public void setAttribute(S solution, V value) {
     solution.setAttribute(getAttributeID(), value);
  }

  @Override
  public Object getAttributeID() {
    return this.getClass() ;
  }
}

Notez que dans cette implémentation, getAttributedID () retourne l'identificateur de classe. Cela signifie que la solution ne peut pas avoir un autre attribut de la même classe.

Example of attrivute: constraints

Les problèmes d'optimisation peuvent être contraints. Cela signifie que pour évaluer la solution, il est nécessaire d'évaluer non seulement la fonction objectif, mais également les contraintes pour appliquer une sorte de mécanisme de traitement de contraintes. SoluttionAttribute est utilisé pour incorporer des informations de contrainte dans Solution.

Le mécanisme de gestion des contraintes par défaut de jMetal est défini dans NSGA-II. Puisqu'il s'agit de ʻOverallConstraintViolation`, les classes suivantes sont préparées.

package org.uma.jmetal.util.solutionattribute.impl;
public class OverallConstraintViolation<S extends Solution<?>> extends GenericSolutionAttribute<S, Double> {
}

Il s'agit d'une classe vide qui étend GenericSolutionAttribute pour spécifier des valeurs continues. Normalement, la contrainte est évaluée dans la classe Solultion comme suit.

package org.uma.jmetal.problem.multiobjective;

/** Class representing problem Binh2 */
public class Binh2 extends AbstractDoubleProblem implements ConstrainedProblem<DoubleSolution> {
  public OverallConstraintViolation<DoubleSolution> overallConstraintViolationDegree ;
  public NumberOfViolatedConstraints<DoubleSolution> numberOfViolatedConstraints ;
  /**
   * Constructor
   * Creates a default instance of the Binh2 problem
   */
  public Binh2() {
    ...
    overallConstraintViolationDegree = new OverallConstraintViolation<DoubleSolution>() ;
    numberOfViolatedConstraints = new NumberOfViolatedConstraints<DoubleSolution>() ;
  }

  /** Evaluate() method */
  @Override
  public void evaluate(DoubleSolution solution) {
     ...
  }

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

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

    constraint[0] = -1.0 * (x0 - 5) * (x0 - 5) - x1 * x1 + 25.0;
    constraint[1] = (x0 - 8) * (x0 - 8) + (x1 + 3) * (x1 + 3) - 7.7;

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

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

Ce code contient également un autre attribut appelé «NumberOfViolatedConstraints» pour définir le nombre de contraintes que la solution spécifiée enfreint.

(Pour ce qui est de ce code, il semble que la valeur de la contrainte soit implémentée de manière à satisfaire la contrainte lorsqu'elle est positive et viole la contrainte lorsqu'elle est négative.)

Example of attribute: ranking

Il peut être encapsulé en utilisant SolutionAttribute. A titre d'exemple, une interface est définie qui attribue des rangs (classement NSGA-II) aux solutions suivantes.

package org.uma.jmetal.util.solutionattribute;

import java.util.List;

/**
 * Ranks a list of solutions according to the dominance relationship
 *
 * @author Antonio J. Nebro <[email protected]>
 */
public interface Ranking<S extends Solution<?>> extends SolutionAttribute<S, Integer>{
  public Ranking<S> computeRanking(List<S> solutionList) ;
  public List<S> getSubfront(int rank) ;
  public int getNumberOfSubfronts() ;
}

Par conséquent, la classe client (par exemple la classe NSGA-II) peut être utilisée simplement comme suit.

Ranking ranking = computeRanking(jointPopulation);

De cette façon, les attributs de la solution sont gérés en interne par la classe qui implémente Ranking et sont cachés de l'algorithme.

Recommended Posts

jMetal Explication - Interface de solution
jMetal Explanation - Interface de l'algorithme
jMetal Explication - Interface du problème
interface