package jcgp; import java.io.File; import jcgp.backend.modules.es.EvolutionaryStrategy; import jcgp.backend.modules.es.MuPlusLambda; import jcgp.backend.modules.es.TournamentSelection; import jcgp.backend.modules.mutator.Mutator; import jcgp.backend.modules.mutator.PointMutator; import jcgp.backend.modules.problem.DigitalCircuit; import jcgp.backend.modules.problem.Problem; import jcgp.backend.modules.problem.SymbolicRegression; import jcgp.backend.modules.problem.TestCaseProblem; import jcgp.backend.parser.ChromosomeParser; import jcgp.backend.parser.FunctionParser; import jcgp.backend.parser.ParameterParser; import jcgp.backend.parser.TestCaseParser; import jcgp.backend.population.Population; import jcgp.backend.resources.Console; import jcgp.backend.resources.ModifiableResources; import jcgp.backend.resources.Resources; /** * * Top-level CGP class. This class is the entry point for a CGP experiment. *
* An instance of JCGP encapsulates the entire experiment. It contains a Resources * object which can be retrieved via a getter. Modules can be selected using their * respective setters and function sets can be selected through the resources. * * The flow of the experiment is controlled using start() and nextGeneration(). The * experiment can be reset with reset(), TODO comment * * * @author Eduardo Pedroni * @see Resources, Module, FunctionSet */ public class JCGP { // make resources private final ModifiableResources resources = new ModifiableResources(); /* * The following arrays contain all available modules. These collections are read by the GUI * when generating menus, so modules not added here will *NOT* be selectable in the GUI. * * Each array is accompanied by a field which contains a reference to the currently selected * module, 0 by default. */ // mutators private Mutator[] mutators = new Mutator[] { new PointMutator(resources) }; private Mutator mutator; // evolutionary algorithms private EvolutionaryStrategy[] evolutionaryStrategies = new EvolutionaryStrategy[] { new MuPlusLambda(resources), new TournamentSelection() }; private EvolutionaryStrategy evolutionaryStrategy; // problem types private Problem[] problems = new Problem[] { new SymbolicRegression(resources), new DigitalCircuit(resources) }; private Problem problem; /* * the population of chromosomes */ private Population population; private boolean finished = false; /** * TODO comment this! * * @param args */ public static void main(String... args) { if (args.length < 1) { System.err.println("JCGP requires at least a .par file."); System.exit(1); } JCGP jcgp = new JCGP(); jcgp.loadParameters(new File(args[0])); if (jcgp.getProblem() instanceof TestCaseProblem) { TestCaseParser.parse(new File(args[2]), (TestCaseProblem) jcgp.getProblem()); } jcgp.start(); } public JCGP() { setEvolutionaryStrategy(0); setMutator(0); setProblem(0); population = new Population(resources); } public ModifiableResources getResources() { return resources; } public Population getPopulation() { return population; } /** * @return the mutators */ public Mutator[] getMutators() { return mutators; } /** * @return the mutator */ public Mutator getMutator() { return mutator; } /** * @return the evolutionaryAlgorithms */ public EvolutionaryStrategy[] getEvolutionaryStrategies() { return evolutionaryStrategies; } /** * @return the evolutionaryAlgorithm */ public EvolutionaryStrategy getEvolutionaryStrategy() { return evolutionaryStrategy; } /** * @return the fitnessFunctions */ public Problem[] getProblems() { return problems; } /** * @return the fitnessFunction */ public Problem getProblem() { return problem; } /** * @param mutator the mutator to set */ public void setMutator(int index) { this.mutator = mutators[index]; } /** * @param evolutionaryStrategy the evolutionaryAlgorithm to set */ public void setEvolutionaryStrategy(int index) { this.evolutionaryStrategy = evolutionaryStrategies[index]; } /** * @param problem the fitnessFunction to set */ public void setProblem(int index) { this.problem = problems[index]; resources.setFunctionSet(problem.getFunctionSet()); } public void nextGeneration() { if (!finished) { problem.evaluate(population, (Resources) resources); reportGeneration(); if (resources.currentGeneration() < resources.generations()) { // we still have generations left to go if (problem.isPerfectSolution(population.getFittest())) { // solution has been found, start next run resources.println("[CGP] Solution found, generation " + resources.currentGeneration() + ", chromosome " + population.getFittestIndex()); if (resources.currentRun() < resources.runs()) { // there are still runs left resources.setCurrentRun(resources.currentRun() + 1); resources.setCurrentGeneration(0); // start a new population population.reinitialise(); } else { // no more generations and no more runs, we're done finished = true; } } else { resources.setCurrentGeneration(resources.currentGeneration() + 1); } } else { // the run has ended, check if any more runs must be done resources.println("[CGP] Solution not found, highest fitness achieved was " + population.getFittest().getFitness() + " by chromosome " + population.getFittestIndex()); if (resources.currentRun() < resources.runs()) { // the run has ended but there are still runs left resources.setCurrentRun(resources.currentRun() + 1); resources.setCurrentGeneration(0); // start a new population population.reinitialise(); } else { // no more generations and no more runs, we're done finished = true; } } } evolutionaryStrategy.evolve(population, mutator, (Resources) resources); } private void reportGeneration() { if (resources.reportInterval() > 0) { if (resources.currentGeneration() % resources.reportInterval() == 0) { resources.println("[CGP] Generation: " + resources.currentGeneration()); } } } public void start() { if (!finished) { while (!finished) { nextGeneration(); } } } public void reset() { finished = false; population = new Population(resources); resources.setCurrentGeneration(1); resources.setCurrentRun(1); resources.println("-----------------------------"); resources.println("New experiment: " + problem.toString()); } public void loadParameters(File file) { ParameterParser.parseParameters(file, resources); FunctionParser.parseFunctions(file, problem); reset(); } public void loadTestCases(File file) { if (problem instanceof TestCaseProblem) { TestCaseParser.parse(file, (TestCaseProblem) problem); } } public void loadChromosome(File file) { ChromosomeParser.parse(file, population.getChromosome(0), resources); } public void saveChromosome(File file, int chromosomeIndex) { ChromosomeParser.save(file, population.getChromosome(chromosomeIndex)); } public boolean isFinished() { return finished; } public void setConsole(Console console) { resources.setConsole(console); } }