/* * Copyright 2007-2013 * Licensed under GNU Lesser General Public License * * This file is part of EpochX: genetic programming software for research * * EpochX 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. * * EpochX 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 EpochX. If not, see <http://www.gnu.org/licenses/>. * * The latest version is available from: http://www.epochx.org */ package org.epochx.ge.init; import static org.epochx.Config.Template.TEMPLATE; import static org.epochx.Population.SIZE; import static org.epochx.ge.Chromosome.MAXIMUM_LENGTH; import org.epochx.*; import org.epochx.event.*; import org.epochx.ge.*; /** * Initialisation method which produces <code>GEIndividual</code>s with fixed length * chromosomes. * * <p> * See the {@link #setup()} method documentation for a list of configuration * parameters used to control this operator. * * @see Full * @see Grow * @see RampedHalfAndHalf * * @since 2.0 */ public class FixedLength implements GEInitialisation, Listener<ConfigEvent> { // Configuration settings private Integer populationSize; private Integer chromosomeLength; private Boolean allowDuplicates; /** * Constructs a <code>FixedLengthInitialisation</code> with control parameters * automatically loaded from the config */ public FixedLength() { this(true); } /** * Constructs a <code>FixedLengthInitialisation</code> with control parameters * initially loaded from the config. If the <code>autoConfig</code> argument is * set to <code>true</code> then the configuration will be automatically updated * when the config is modified. * * @param autoConfig whether this operator should automatically update its * configuration settings from the config */ public FixedLength(boolean autoConfig) { // Default config values allowDuplicates = true; setup(); if (autoConfig) { EventManager.getInstance().add(ConfigEvent.class, this); } } /** * Sets up this operator with the appropriate configuration settings. * This method is called whenever a <code>ConfigEvent</code> occurs for a * change in any of the following configuration parameters: * <ul> * <li>{@link Population#SIZE} * <li>{@link GenericChromosome#MAXIMUM_LENGTH} * <li>{@link InitialisationMethod#ALLOW_DUPLICATES} (default: <code>true</code>) * </ul> */ protected void setup() { populationSize = Config.getInstance().get(SIZE); allowDuplicates = Config.getInstance().get(ALLOW_DUPLICATES, allowDuplicates); chromosomeLength = Config.getInstance().get(MAXIMUM_LENGTH); } /** * Receives configuration events and triggers this operator to reconfigure * if the <code>ConfigEvent</code> is for one of its required parameters * * @param event {@inheritDoc} */ @Override public void onEvent(ConfigEvent event) { if (event.isKindOf(TEMPLATE, SIZE, ALLOW_DUPLICATES, MAXIMUM_LENGTH)) { setup(); } } /** * Creates a population of new <code>GEIndividuals</code>. Each individual is * created by a call to the<code>createIndividual</code> method. The size of the * population will be equal to the {@link Population#SIZE} config parameter. * If the {@link InitialisationMethod#ALLOW_DUPLICATES} config parameter is * set to <code>false</code> then the individuals in the population will be * unique according to their <code>equals</code> methods. By default, duplicates * are allowed. * * @return a population of <code>GEIndividual</code> objects */ @Override public Population createPopulation() { EventManager.getInstance().fire(new InitialisationEvent.StartInitialisation()); Population population = new Population(); for (int i = 0; i < populationSize; i++) { GEIndividual individual; do { individual = createIndividual(); } while (!allowDuplicates && population.contains(individual)); population.add(individual); } EventManager.getInstance().fire(new InitialisationEvent.EndInitialisation(population)); return population; } /** * Constructs a new <code>GEIndividual</code> instance with a fixed length * chromosome, as determined by the {@link Chromosome#MAXIMUM_LENGTH} * config parameter. * * @return a new individual with a fixed length chromosome */ @Override public GEIndividual createIndividual() { if (chromosomeLength < 1) { throw new IllegalStateException("chromosome length must be 1 or greater"); } Chromosome chromosome = new Chromosome(); for (int i = 0; i < chromosomeLength; i++) { chromosome.extend(); } return new GEIndividual(chromosome); } /** * Returns the length of chromosomes that all individuals are generated with * * @return the length of generated chromosomes */ public int getChromosomeLength() { return chromosomeLength; } /** * Sets the length of chromosomes for individuals. If automatic * configuration is enabled then any value set here will be overwritten by * the {@link GenericChromosome#MAXIMUM_LENGTH} configuration setting on the next * config event. * * @param chromosomeLength the fixed length to use for chromosomes */ public void setChromosomeLength(int chromosomeLength) { this.chromosomeLength = chromosomeLength; } /** * Returns whether or not duplicates are currently allowed in generated * populations * * @return <code>true</code> if duplicates are currently allowed in populations * generated by the <code>createPopulation</code> method and * <code>false</code> otherwise */ public boolean isDuplicatesEnabled() { return allowDuplicates; } /** * Sets whether duplicates should be allowed in populations that are * generated. If automatic configuration is enabled then any value set here * will be overwritten by the {@link InitialisationMethod#ALLOW_DUPLICATES} * configuration setting on the next config event. * * @param allowDuplicates whether duplicates should be allowed in * populations that are generated */ public void setDuplicatesEnabled(boolean allowDuplicates) { this.allowDuplicates = allowDuplicates; } /** * Returns the number of individuals to be generated in a population created * by the <code>createPopulation</code> method * * @return the size of the populations generated */ public int getPopulationSize() { return populationSize; } /** * Sets the number of individuals to be generated in a population created * by the <code>createPopulation</code> method. If automatic configuration is * enabled thenAny value set here will be overwritten by the * {@link Population#SIZE} configuration setting on the next config event. * * @param size the size of the populations generated */ public void setPopulationSize(int size) { this.populationSize = size; } }