diff options
Diffstat (limited to 'src/jcgp/backend/modules/problem/Problem.java')
-rw-r--r-- | src/jcgp/backend/modules/problem/Problem.java | 142 |
1 files changed, 120 insertions, 22 deletions
diff --git a/src/jcgp/backend/modules/problem/Problem.java b/src/jcgp/backend/modules/problem/Problem.java index 368d512..721b9b3 100644 --- a/src/jcgp/backend/modules/problem/Problem.java +++ b/src/jcgp/backend/modules/problem/Problem.java @@ -4,6 +4,8 @@ import java.io.File; import jcgp.backend.function.FunctionSet; import jcgp.backend.modules.Module; +import jcgp.backend.parameters.DoubleParameter; +import jcgp.backend.parameters.monitors.DoubleMonitor; import jcgp.backend.population.Chromosome; import jcgp.backend.population.Population; import jcgp.backend.resources.ModifiableResources; @@ -11,11 +13,18 @@ import jcgp.backend.resources.Resources; /** * Defines the general behaviour of a CGP problem. The primary function of Problem - * is to evaluate a population and assign + * is to evaluate a population and assign a fitness value to each chromosome. + * <br> + * By convention, the population should be sorted into ascending order of fitness. The + * reason for this is because high fitness is not necessarily better - some problem types + * might treat 0 as the best fitness. In order for the evolutionary strategy to be able to + * pick chromosomes by fitness, the safest way is to sort them such that the last chromosome + * is the fittest. * <br><br> - * Parameters may be specified to control the implemented problem. Any parameters - * returned by {@code getLocalParameters()} should be displayed by the user interface, - * if it is being used. See {@link Parameter} for more information. + * When extending this class, the constructor should call a couple methods in order to + * properly construct the problem type: {@code setFunctionSet()} and {@code setFileExtension()}, + * with the respective arguments. As with all subclasses of {@code Module}, {@code setName()} and + * {@code registerParameters()} should be used where appropriate as well. * <br><br> * It is advisable to use {@code Resources.reportln()} and {@code Resources.report()} * to print any relevant information. Note that reportln() and report() are affected @@ -24,44 +33,133 @@ import jcgp.backend.resources.Resources; * See {@link Resources} for more information. * * @see Module - * * @author Eduardo Pedroni * */ -public abstract class Problem implements Module { +public abstract class Problem extends Module { - protected FunctionSet functionSet; + private FunctionSet functionSet; private String fileExtension = ".*"; - private String name = this.getClass().getSimpleName(); - public abstract void evaluate(Population population, Resources resources); + protected DoubleParameter maxFitness, bestFitness; - public FunctionSet getFunctionSet() { - return functionSet; + /** + * Initialises the two problem-wide parameters, maxFitness and bestFitness. + */ + public Problem() { + maxFitness = new DoubleMonitor(0, "Max fitness"); + bestFitness = new DoubleMonitor(0, "Best fitness"); + registerParameters(maxFitness, bestFitness); } - public abstract boolean isPerfectSolution(Chromosome fittest); + /** + * The most important method of the problem type. This is called once + * per generation, when the new population has been generated. + * <br><br> + * The basic functionality of this method is to loop through all chromosomes + * in the population and decode them according to the problem type. The + * fitness of each chromosome is then calculated using the problem data + * or otherwise (subjective problem types such as art generation might + * leave fitness evaluations up to the user) and assigned to the appropriate + * chromosome. + * <br><br> + * In addition, realisations of this method should update the value of + * bestFitness as appropriate, since the value of this parameter is displayed + * if a GUI is in use. + * + * @param population the population to be evaluated. + * @param resources parameters and utilities for optional reference. + */ + public abstract void evaluate(Population population, Resources resources); + + /** + * Used to assert whether a given chromosome is a perfect solution + * to the problem. It is up to the problem to define what qualifies + * a perfect solution, as some problems (subject ones such as music and + * art evolution, for example) might not have perfect solutions at all. + * <br><br> + * Note that if this method returns true, the experiment will move on + * to the next run, or finish if no more runs are left. + * + * @param candidate the potentially perfect chromosome. + * @return true if the argument is a perfect solution. + */ + public abstract boolean isPerfectSolution(Chromosome candidate); + /** + * Used to assert whether a given chromosome is an improvement over + * the current best chromosome. A typical implementation of this method + * will simply compare chromosome fitness values, though the problem type + * is free to implement this in any way. + * + * @param candidate the potentially fitter chromosome. + * @return true if the argument is fitter than the currently fittest chromosome. + */ + public abstract boolean isImprovement(Chromosome candidate); + + /** + * Parses the specified file and uses the parsed data to + * set up the problem type instance appropriately. Any necessary + * resource changes can be performed using the provided {@code ModifiableResources} + * instance. + * <br><br> + * In addition, realisations of this method should update the value of + * maxFitness where appropriate, as this may be displayed to the user + * if a GUI is in use. + * + * @param file the data file to parse. + * @param resources a modifiable reference to the experiment's resources. + */ public abstract void parseProblemData(File file, ModifiableResources resources); - public void setFileExtension(String fileExtension) { + /** + * For internal use in subclass constructor, sets the functions to be + * used for this problem type. See {@link FunctionSet} for more details. + * + * @param newFunctionSet the function set to use. + */ + protected void setFunctionSet(FunctionSet newFunctionSet) { + this.functionSet = newFunctionSet; + } + + /** + * @return the FunctionSet object used by this problem type. + */ + public FunctionSet getFunctionSet() { + return functionSet; + } + + /** + * For internal use in subclass constructors, sets the file extension accepted + * by this problem type's parser. This is used by the GUI to filter loaded files + * by extension in a file chooser. File extensions should be set in the form ".*", + * so for plain text files, ".txt" would be used. + * + * @param fileExtension the accepted file extension. + */ + protected void setFileExtension(String fileExtension) { this.fileExtension = fileExtension; } + /** + * @return the file extension accepted by this problem type for problem data files. + */ public String getFileExtension() { return fileExtension; } - public void setProblemName(String newName) { - this.name = newName; - } - - public String getProblemName() { - return name; + /** + * @return the current best fitness, in other words, the fitness + * value of the fittest chromosome in the current generation. + */ + public double getBestFitness() { + return bestFitness.get(); } - @Override - public String toString() { - return name; + /** + * Resets the bestFitness parameter. + */ + public void reset() { + bestFitness.set(0); } } |