// Solution.java // // Author: // Antonio J. Nebro <antonio@lcc.uma.es> // Juan J. Durillo <durillo@lcc.uma.es> // // Description: // // Copyright (c) 2011 Antonio J. Nebro, Juan J. Durillo // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. package jmetal.core; import jmetal.encodings.variable.Binary; import java.io.Serializable; /** * Class representing a solution for a problem. */ public class Solution implements Serializable { /** * Stores the problem */ private Problem problem_ ; /** * Stores the type of the encodings.variable */ private SolutionType type_ ; /** * Stores the decision variables of the solution. */ private Variable[] variable_ ; /** * Stores the objectives values of the solution. */ private final double [] objective_ ; /** * Stores the number of objective values of the solution */ private int numberOfObjectives_ ; /** * Stores the so called fitness value. Used in some metaheuristics */ private double fitness_ ; /** * Used in algorithm AbYSS, this field is intended to be used to know * when a <code>Solution</code> is marked. */ private boolean marked_ ; /** * Stores the so called rank of the solution. Used in NSGA-II */ private int rank_ ; /** * Stores the overall constraint violation of the solution. */ private double overallConstraintViolation_ ; /** * Stores the number of constraints violated by the solution. */ private int numberOfViolatedConstraints_ ; /** * This field is intended to be used to know the location of * a solution into a <code>SolutionSet</code>. Used in MOCell */ private int location_ ; /** * Stores the distance to his k-nearest neighbor into a * <code>SolutionSet</code>. Used in SPEA2. */ private double kDistance_ ; /** * Stores the crowding distance of the the solution in a * <code>SolutionSet</code>. Used in NSGA-II. */ private double crowdingDistance_ ; /** * Stores the distance between this solution and a <code>SolutionSet</code>. * Used in AbySS. */ private double distanceToSolutionSet_ ; /** * Constructor. */ public Solution() { problem_ = null ; marked_ = false ; overallConstraintViolation_ = 0.0 ; numberOfViolatedConstraints_ = 0 ; type_ = null ; variable_ = null ; objective_ = null ; } // Solution /** * Constructor * @param numberOfObjectives Number of objectives of the solution * * This constructor is used mainly to read objective values from a file to * variables of a SolutionSet to apply quality indicators */ public Solution(int numberOfObjectives) { numberOfObjectives_ = numberOfObjectives; objective_ = new double[numberOfObjectives]; } /** * Constructor. * @param problem The problem to solve * @throws ClassNotFoundException */ public Solution(Problem problem) throws ClassNotFoundException{ problem_ = problem ; type_ = problem.getSolutionType() ; numberOfObjectives_ = problem.getNumberOfObjectives() ; objective_ = new double[numberOfObjectives_] ; // Setting initial values fitness_ = 0.0 ; kDistance_ = 0.0 ; crowdingDistance_ = 0.0 ; distanceToSolutionSet_ = Double.POSITIVE_INFINITY ; //<- //variable_ = problem.solutionType_.createVariables() ; variable_ = type_.createVariables() ; } // Solution static public Solution getNewSolution(Problem problem) throws ClassNotFoundException { return new Solution(problem) ; } /** * Constructor * @param problem The problem to solve */ public Solution(Problem problem, Variable [] variables){ problem_ = problem ; type_ = problem.getSolutionType() ; numberOfObjectives_ = problem.getNumberOfObjectives() ; objective_ = new double[numberOfObjectives_] ; // Setting initial values fitness_ = 0.0 ; kDistance_ = 0.0 ; crowdingDistance_ = 0.0 ; distanceToSolutionSet_ = Double.POSITIVE_INFINITY ; //<- variable_ = variables ; } // Constructor /** * Copy constructor. * @param solution Solution to copy. */ public Solution(Solution solution) { problem_ = solution.problem_ ; type_ = solution.type_; numberOfObjectives_ = solution.getNumberOfObjectives(); objective_ = new double[numberOfObjectives_]; for (int i = 0; i < objective_.length;i++) { objective_[i] = solution.getObjective(i); } // for //<- variable_ = type_.copyVariables(solution.variable_) ; overallConstraintViolation_ = solution.getOverallConstraintViolation(); numberOfViolatedConstraints_ = solution.getNumberOfViolatedConstraint(); distanceToSolutionSet_ = solution.getDistanceToSolutionSet(); crowdingDistance_ = solution.getCrowdingDistance(); kDistance_ = solution.getKDistance(); fitness_ = solution.getFitness(); marked_ = solution.isMarked(); rank_ = solution.getRank(); location_ = solution.getLocation(); } // Solution /** * Sets the distance between this solution and a <code>SolutionSet</code>. * The value is stored in <code>distanceToSolutionSet_</code>. * @param distance The distance to a solutionSet. */ public void setDistanceToSolutionSet(double distance){ distanceToSolutionSet_ = distance; } // SetDistanceToSolutionSet /** * Gets the distance from the solution to a <code>SolutionSet</code>. * <b> REQUIRE </b>: this method has to be invoked after calling * <code>setDistanceToPopulation</code>. * @return the distance to a specific solutionSet. */ public double getDistanceToSolutionSet(){ return distanceToSolutionSet_; } // getDistanceToSolutionSet /** * Sets the distance between the solution and its k-nearest neighbor in * a <code>SolutionSet</code>. The value is stored in <code>kDistance_</code>. * @param distance The distance to the k-nearest neighbor. */ public void setKDistance(double distance){ kDistance_ = distance; } // setKDistance /** * Gets the distance from the solution to his k-nearest nighbor in a * <code>SolutionSet</code>. Returns the value stored in * <code>kDistance_</code>. <b> REQUIRE </b>: this method has to be invoked * after calling <code>setKDistance</code>. * @return the distance to k-nearest neighbor. */ double getKDistance(){ return kDistance_; } // getKDistance /** * Sets the crowding distance of a solution in a <code>SolutionSet</code>. * The value is stored in <code>crowdingDistance_</code>. * @param distance The crowding distance of the solution. */ public void setCrowdingDistance(double distance){ crowdingDistance_ = distance; } // setCrowdingDistance /** * Gets the crowding distance of the solution into a <code>SolutionSet</code>. * Returns the value stored in <code>crowdingDistance_</code>. * <b> REQUIRE </b>: this method has to be invoked after calling * <code>setCrowdingDistance</code>. * @return the distance crowding distance of the solution. */ public double getCrowdingDistance(){ return crowdingDistance_; } // getCrowdingDistance /** * Sets the fitness of a solution. * The value is stored in <code>fitness_</code>. * @param fitness The fitness of the solution. */ public void setFitness(double fitness) { fitness_ = fitness; } // setFitness /** * Gets the fitness of the solution. * Returns the value of stored in the encodings.variable <code>fitness_</code>. * <b> REQUIRE </b>: This method has to be invoked after calling * <code>setFitness()</code>. * @return the fitness. */ public double getFitness() { return fitness_; } // getFitness /** * Sets the value of the i-th objective. * @param i The number identifying the objective. * @param value The value to be stored. */ public void setObjective(int i, double value) { objective_[i] = value; } // setObjective /** * Returns the value of the i-th objective. * @param i The value of the objective. */ public double getObjective(int i) { return objective_[i]; } // getObjective /** * Returns the number of objectives. * @return The number of objectives. */ public int getNumberOfObjectives() { if (objective_ == null) return 0 ; else return numberOfObjectives_; } // getNumberOfObjectives /** * Returns the number of decision variables of the solution. * @return The number of decision variables. */ public int numberOfVariables() { return problem_.getNumberOfVariables() ; } // numberOfVariables /** * Returns a string representing the solution. * @return The string. */ public String toString() { String aux=""; for (int i = 0; i < this.numberOfObjectives_; i++) aux = aux + this.getObjective(i) + " "; return aux; } // toString /** * Returns the decision variables of the solution. * @return the <code>DecisionVariables</code> object representing the decision * variables of the solution. */ public Variable[] getDecisionVariables() { return variable_ ; } // getDecisionVariables /** * Sets the decision variables for the solution. * @param variables The <code>DecisionVariables</code> object * representing the decision variables of the solution. */ public void setDecisionVariables(Variable [] variables) { variable_ = variables ; } // setDecisionVariables public Problem getProblem() { return problem_ ; } /** * Indicates if the solution is marked. * @return true if the method <code>marked</code> has been called and, after * that, the method <code>unmarked</code> hasn't been called. False in other * case. */ public boolean isMarked() { return this.marked_; } // isMarked /** * Establishes the solution as marked. */ public void marked() { this.marked_ = true; } // marked /** * Established the solution as unmarked. */ public void unMarked() { this.marked_ = false; } // unMarked /** * Sets the rank of a solution. * @param value The rank of the solution. */ public void setRank(int value){ this.rank_ = value; } // setRank /** * Gets the rank of the solution. * <b> REQUIRE </b>: This method has to be invoked after calling * <code>setRank()</code>. * @return the rank of the solution. */ public int getRank(){ return this.rank_; } // getRank /** * Sets the overall constraints violated by the solution. * @param value The overall constraints violated by the solution. */ public void setOverallConstraintViolation(double value) { this.overallConstraintViolation_ = value; } // setOverallConstraintViolation /** * Gets the overall constraint violated by the solution. * <b> REQUIRE </b>: This method has to be invoked after calling * <code>overallConstraintViolation</code>. * @return the overall constraint violation by the solution. */ public double getOverallConstraintViolation() { return this.overallConstraintViolation_; } //getOverallConstraintViolation /** * Sets the number of constraints violated by the solution. * @param value The number of constraints violated by the solution. */ public void setNumberOfViolatedConstraint(int value) { this.numberOfViolatedConstraints_ = value; } //setNumberOfViolatedConstraint /** * Gets the number of constraint violated by the solution. * <b> REQUIRE </b>: This method has to be invoked after calling * <code>setNumberOfViolatedConstraint</code>. * @return the number of constraints violated by the solution. */ public int getNumberOfViolatedConstraint() { return this.numberOfViolatedConstraints_; } // getNumberOfViolatedConstraint /** * Sets the location of the solution into a solutionSet. * @param location The location of the solution. */ public void setLocation(int location) { this.location_ = location; } // setLocation /** * Gets the location of this solution in a <code>SolutionSet</code>. * <b> REQUIRE </b>: This method has to be invoked after calling * <code>setLocation</code>. * @return the location of the solution into a solutionSet */ public int getLocation() { return this.location_; } // getLocation /** * Sets the type of the encodings.variable. * @param type The type of the encodings.variable. */ //public void setType(String type) { // type_ = Class.forName("") ; //} // setType /** * Sets the type of the encodings.variable. * @param type The type of the encodings.variable. */ public void setType(SolutionType type) { type_ = type ; } // setType /** * Gets the type of the encodings.variable * @return the type of the encodings.variable */ public SolutionType getType() { return type_; } // getType /** * Returns the aggregative value of the solution * @return The aggregative value. */ public double getAggregativeValue() { double value = 0.0; for (int i = 0; i < getNumberOfObjectives(); i++){ value += getObjective(i); } return value; } // getAggregativeValue /** * Returns the number of bits of the chromosome in case of using a binary * representation * @return The number of bits if the case of binary variables, 0 otherwise * This method had a bug which was fixed by Rafael Olaechea */ public int getNumberOfBits() { int bits = 0 ; for (int i = 0; i < variable_.length ; i++) if ((variable_[i].getVariableType() == jmetal.encodings.variable.Binary.class) || (variable_[i].getVariableType() == jmetal.encodings.variable.BinaryReal.class)) bits += ((Binary)(variable_[i])).getNumberOfBits() ; return bits ; } // getNumberOfBits } // Solution