aboutsummaryrefslogtreecommitdiffstats
path: root/src/jcgp/backend/modules/problem/Problem.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/jcgp/backend/modules/problem/Problem.java')
-rw-r--r--src/jcgp/backend/modules/problem/Problem.java142
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);
}
}