package ac.essex.gp.problems;

import ac.essex.gp.params.GPParams;
import ac.essex.gp.individuals.Individual;
import ac.essex.gp.util.DataStack;
import ac.essex.gp.Evolve;

/**
 * Basic Problem Class upon which all GP problems are based.
 * The two most important methods are the initialise() and evaluate() methods
 * where the training data is loaded, and individuals fitness assessed respectively.
 *
 * Any class implementing these methods can be plugged into the Evolve class which runs
 * the GP simulation on the problem.
 *
 * @author Olly Oechsle, University of Essex, Date: 15-Jan-2007
 * @version 1.0
 */
public abstract class Problem {

    /**
     * Where the problem can customise its GP parameters.
     */
    public abstract void customiseParameters(GPParams params);

    /**
     * Provides a name for the problem so that it can be identified via the
     * user interface.
     */
    public abstract String getName();

    /**
     * Returns how many classes the problem must solve
     */
    public abstract int getClassCount();

    /**
     * Initialises the problem. This is where the training data is loaded
     * and the GP params object initialised with Nodes to use. The return
     * object should also be set up.
     */
    public abstract void initialise(Evolve e, GPParams params);

    /**
     * Evaluates a single individual, fitness should be assigned using the
     * setKozaFitness() method on the individual.
     */
    public abstract void evaluate(Individual ind, DataStack data);

    /**
     * Allows the Problem to return some kind of data after evaluating the best
     * individual of a generation. In imaging situations, this is usually an image
     * that can be displayed in the GUI to indicate how well the GP is progressing.
     * It is not necessary to implement this function.
     */
    public Object describe(Individual ind, DataStack data, int index) {
        return null;
    }

    /**
     * A hook which allows the problem to execute additional logic just as it is finished,
     * or indeed start up a new Evolution Process.
     */
    public void onFinish(Individual bestIndividual, Evolve e) {
        // by default do nothing
    }

}
