Java tutorial
/* * This file is part of JGAP. * * JGAP offers a dual license model containing the LGPL as well as the MPL. * * For licensing information please see the file license.txt included with JGAP * or have a look at the top of class org.jgap.Chromosome which representatively * includes the JGAP license policy applicable for any file delivered with JGAP. */ package org.jgap.gp.impl; import java.io.*; import java.util.*; import org.apache.commons.lang.builder.*; import org.jgap.*; import org.jgap.distr.*; import org.jgap.event.*; import org.jgap.gp.*; import org.jgap.gp.terminal.*; import org.jgap.impl.*; import org.jgap.util.*; /** * Configuration for a GP. * * @author Klaus Meffert * @since 3.0 */ public class GPConfiguration extends Configuration { /** String containing the CVS revision. Read out via reflection!*/ private final static String CVS_REVISION = "$Revision: 1.52 $"; /**@todo introduce lock for configuration*/ /** * References the current fitness function that will be used to evaluate * chromosomes during the natural selection process. */ private GPFitnessFunction m_objectiveFunction; /** * Internal stack, see PushCommand for example. */ private /*transient*/ Stack m_stack = new Stack(); /** * Internal memory, see StoreTerminalCommand for example. */ private transient Culture m_memory = new Culture(50); private transient Hashtable<String, char[][]> m_matrices; /** * The probability that a crossover operation is chosen during evolution. Must * be between 0.0d and 1.0d, inclusive. */ private double m_crossoverProb = 0.9d; /** * The probability that a reproduction operation is chosen during evolution. * Must be between 0.0d and 1.0d. crossoverProb + reproductionProb must equal * 1.0d. */ private double m_reproductionProb = 0.1d; /** * The probability that a node is mutated during growing a program. */ private double m_mutationProb = 0.1d; /** * The probability that the arity of a node is changed during growing a * program. */ private double m_dynArityProb = 0.08d; /** * Percentage of the population that will be filled with new individuals * during evolution. Must be between 0.0d and 1.0d. */ private double m_newChromsPercent = 0.3d; /** * In crossover: If random number (0..1) < this value, then choose a function * otherwise a terminal. */ private double m_functionProb = 0.9d; /** * The maximum depth of an individual resulting from crossover. */ private int m_maxCrossoverDepth = 17; /** * The maximum depth of an individual when the world is created. */ private int m_maxInitDepth = 7; /** * The minimum depth of an individual when the world is created. */ private int m_minInitDepth = 2; /** * The method of choosing an individual to perform an evolution operation on. */ private INaturalGPSelector m_selectionMethod; /** * The method of crossing over two individuals during evolution. */ private CrossMethod m_crossMethod; /** * True: Set of available functions must contain any "type of function" that * may be needed during construction of a new program. A "type of function" * is, for instance, a terminal with return type CommandGene.IntegerClass. */ private boolean m_strictProgramCreation; /** * If m_strictProgramCreation is false: Maximum number of tries to construct * a valid program. */ private int m_programCreationMaxTries = 5; /** * The fitness evaluator. See interface IGPFitnessEvaluator for details. */ private IGPFitnessEvaluator m_fitnessEvaluator; private INodeValidator m_nodeValidator; private ISingleNodeValidator m_singleNodeValidator; /** * Internal flag to display a warning only once, in case a program could not * be evolved with the allowed maximum number of nodes. * * @since 3.2 */ private transient boolean m_warningPrinted; /** * Prototype of a valid program. May be cloned if needed (do not reference * it!). * * @since 3.2 */ private IGPProgram m_prototypeProgram; private boolean m_useProgramCache = false; private Map m_variables; private transient Map m_programCache; /** * Holds the central configurable factory for creating default objects. * * @author Klaus Meffert * @since 2.6 */ private transient IJGAPFactory m_factory; /** * For initializing GP programs before random creation. * * @author Klaus Meffert * @since 2.6 */ private IGPInitStrategy m_initStrategy; /** * TRUE: Activate methods checkErroneousPop and checkErroneousProg in class * GPGenotype. */ private boolean m_verify; /** * TRUE: Do not clone command genes when creating a new GP program in * ProgramChromosome. * * @author Klaus Meffert * @since 3.4.3 */ private boolean m_noCommandGeneCloning; /** * Constructor utilizing the FitnessProportionateSelection. * * @throws InvalidConfigurationException * * @author Klaus Meffert * @since 3.0 */ public GPConfiguration() throws InvalidConfigurationException { this("", null); } public GPConfiguration(String a_id, String a_name) throws InvalidConfigurationException { super(a_id, a_name); init(true); m_selectionMethod = new TournamentSelector(3); } /** * Constructs a configuration with an informative name but without a unique * ID. This practically prevents more than one configurations to be * instantiated within the same thread. * * @param a_name informative name of the configuration, may be null * @throws InvalidConfigurationException * * @author Klaus Meffert */ public GPConfiguration(final String a_name) throws InvalidConfigurationException { this(); setName(a_name); } /** * Sets a GP fitness evaluator, such as * org.jgap.gp.impl.DefaultGPFitnessEvaluator. * * @param a_evaluator the fitness evaluator to set * * @author Klaus Meffert * @since 3.1 */ public void setGPFitnessEvaluator(IGPFitnessEvaluator a_evaluator) { m_fitnessEvaluator = a_evaluator; } /** * Helper for construction. * * @param a_fullInit true set event manager, random generator and fitness * evaluator to defauklt * @throws InvalidConfigurationException * * @author Klaus Meffert * @since 3.1 */ protected void init(boolean a_fullInit) throws InvalidConfigurationException { /**@todo make reusable in class Configuration and reuse here from Configuration*/ // Create factory for being able to configure the used default objects, // like random generators or fitness evaluators. // -------------------------------------------------------------------- String clazz = System.getProperty(PROPERTY_JGAPFACTORY_CLASS); if (clazz != null && clazz.length() > 0) { try { m_factory = (IJGAPFactory) Class.forName(clazz).newInstance(); } catch (Throwable ex) { throw new RuntimeException( "Class " + clazz + " could not be instantiated" + " as type IJGAPFactory"); } } else { m_factory = new JGAPFactory(false); } if (m_factory == null) { throw new IllegalStateException("JGAPFactory not registered!"); } m_programCache = new HashMap(50); m_matrices = new Hashtable(); if (a_fullInit) { m_variables = new Hashtable(); m_crossMethod = new BranchTypingCross(this); setEventManager(new EventManager()); setRandomGenerator(new StockRandomGenerator()); setGPFitnessEvaluator(new DefaultGPFitnessEvaluator()); } } /** * Constructor utilizing the FitnessProportionateSelection. * * @param a_selectionMethod the selection method to use * @throws InvalidConfigurationException * * @author Klaus Meffert * @since 3.1 */ public GPConfiguration(INaturalGPSelector a_selectionMethod) throws InvalidConfigurationException { super(); init(true); m_selectionMethod = a_selectionMethod; } /** * Sets the selection method to use. * @param a_method the selection method to use * * @author Klaus Meffert * @since 3.1 */ public void setSelectionMethod(INaturalGPSelector a_method) { if (a_method == null) { throw new IllegalArgumentException("Selection method must not be null"); } m_selectionMethod = a_method; } /** * Sets the crossover method to use. * @param a_method the crossover method to use * * @author Klaus Meffert * @since 3.1 */ public void setCrossoverMethod(CrossMethod a_method) { if (a_method == null) { throw new IllegalArgumentException("Crossover method must not be null"); } m_crossMethod = a_method; } public synchronized void verifyStateIsValid() throws InvalidConfigurationException { // Do nothing in here. // ------------------- } public synchronized void addGeneticOperator(GeneticOperator a_operatorToAdd) throws InvalidConfigurationException { throw new UnsupportedOperationException("Use addGeneticOperator(GPGeneticOperator) instead!"); } // /**@todo implement something like that*/ // public synchronized void addGeneticOperator(IGPGeneticOperator a_operatorToAdd) // throws InvalidConfigurationException { // } public double getCrossoverProb() { return m_crossoverProb; } public void setCrossoverProb(float a_crossoverProb) { m_crossoverProb = a_crossoverProb; } public double getReproductionProb() { return m_reproductionProb; } public void setReproductionProb(float a_reproductionProb) { m_reproductionProb = a_reproductionProb; } /** * @return probability for mutation of a node during growing a program * * @author Klaus Meffert * @since 3.3.1 */ public double getMutationProb() { return m_mutationProb; } /** * @param a_mutationProb probability for mutation of a node during growing a * program * * @author Klaus Meffert * @since 3.3.1 */ public void setMutationProb(float a_mutationProb) { m_mutationProb = a_mutationProb; } /** * @return probability for dynamizing the arity of a node during growing a * program * * @author Klaus Meffert * @since 3.4 */ public double getDynamizeArityProb() { return m_dynArityProb; } /** * @param a_dynArityProb probability for dynamizing the arity of a node during * growing a program * * @author Klaus Meffert * @since 3.4 */ public void setDynamizeArityProb(float a_dynArityProb) { m_dynArityProb = a_dynArityProb; } /** * @param a_functionProb probability that a function instead of a terminal * is chosen in crossing over (between 0 and 1) * * @author Klaus Meffert * @since 3.2 */ public void setFunctionProb(double a_functionProb) { m_functionProb = a_functionProb; } /** * @return probability that a function instead of a terminal is chosen in * crossing over * * @author Klaus Meffert * @since 3.2 */ public double getFunctionProb() { return m_functionProb; } public void setNewChromsPercent(double a_newChromsPercent) { if (m_newChromsPercent >= 1.0d) { throw new IllegalArgumentException("Parameter value must be smaller than 1!"); } m_newChromsPercent = a_newChromsPercent; } public double getNewChromsPercent() { return m_newChromsPercent; } public int getMaxCrossoverDepth() { return m_maxCrossoverDepth; } public void setMaxCrossoverDepth(int a_maxCrossoverDepth) { m_maxCrossoverDepth = a_maxCrossoverDepth; } public INaturalGPSelector getSelectionMethod() { return m_selectionMethod; } public CrossMethod getCrossMethod() { return m_crossMethod; } public int getMaxInitDepth() { return m_maxInitDepth; } public void setMaxInitDepth(int a_maxDepth) { m_maxInitDepth = a_maxDepth; } public int getMinInitDepth() { return m_minInitDepth; } public void setMinInitDepth(int a_minDepth) { m_minInitDepth = a_minDepth; } public void pushToStack(Object a_value) { m_stack.push(a_value); } public Object popFromStack() { return m_stack.pop(); } public Object peekStack() { return m_stack.peek(); } public int stackSize() { return m_stack.size(); } public void clearStack() { m_stack.clear(); } /** * Stores a value in the internal memory. * * @param a_name named index of the memory cell * @param a_value the value to store * * @author Klaus Meffert * @since 3.0 */ public void storeInMemory(String a_name, Object a_value) { m_memory.set(a_name, a_value, -1); } /** * Creates an instance of a matrix with a unique name. * * @param a_name the name of the matrix * @param a_cols number of columns the matrix should have * @param a_rows number of rows the matrix should have * * @author Klaus Meffert * @since 3.4.3 */ public void createMatrix(String a_name, int a_cols, int a_rows) { if (a_name == null || a_name.length() < 1) { throw new IllegalArgumentException("Matrix name must not be empty!"); } if (a_cols < 1 || a_rows < 1) { throw new IllegalArgumentException("Number of colums and rows must be greater than zero!"); } char[][] m_matrix = new char[a_cols][a_rows]; m_matrices.put(a_name, m_matrix); } /** * Sets a matrix field with a value. * * @param a_name the name of the matrix * @param a_col column in the matrix * @param a_row row in the matrix * @param a_value the value to set in the matrix at given column and row * * @author Klaus Meffert * @since 3.4.3 */ public void setMatrix(String a_name, int a_col, int a_row, char a_value) { char[][] m_matrix = m_matrices.get(a_name); if (m_matrix == null) { throw new IllegalArgumentException("Matrix with name " + a_name + " not found!"); } m_matrix[a_col][a_row] = a_value; } /** * Sets a matrix field with a value. * * @param a_name the name of the matrix * @param a_col column in the matrix * @param a_row row in the matrix * @param a_value the value to set in the matrix at given column and row * * @author Klaus Meffert * @since 3.6 */ public void setMatrix(String a_name, int a_col, int a_row, int a_value) { char[][] m_matrix = m_matrices.get(a_name); if (m_matrix == null) { throw new IllegalArgumentException("Matrix with name " + a_name + " not found!"); } m_matrix[a_col][a_row] = (char) a_value; } /** * Resets the matrix by filling it with a given character. * * @param a_name the name of the matrix * @param a_filler the character to fill the whole matrix with * * @author Klaus Meffert * @since 3.4.3 */ public void resetMatrix(String a_name, char a_filler) { char[][] m_matrix = m_matrices.get(a_name); if (m_matrix == null) { throw new IllegalArgumentException("Matrix with name " + a_name + " not found!"); } for (int col = 0; col < m_matrix.length; col++) { for (int row = 0; row < m_matrix[col].length; row++) { m_matrix[col][row] = a_filler; } } } /** * Reads a matrix cell and returns the value. * * @param a_name the name of the matrix * @param a_col the column to read * @param a_row the row to read * @return the value in the matrix * * @author Klaus Meffert * @since 3.4.3 */ public char readMatrix(String a_name, int a_col, int a_row) { char[][] m_matrix = m_matrices.get(a_name); if (m_matrix == null) { throw new IllegalArgumentException("Matrix with name " + a_name + " not found!"); } return m_matrix[a_col][a_row]; } /** * Retrieves a named matrix. * * @param a_name the name of the matrix * @return the matrix itself * * @author Klaus Meffert * @since 3.4.3 */ public char[][] getMatrix(String a_name) { char[][] m_matrix = m_matrices.get(a_name); return m_matrix; } /** * Stores a value in the internal matrix memory. * * @param a_x the first coordinate of the matrix (width) * @param a_y the second coordinate of the matrix (height) * @param a_value the value to store * @return created or used memory cell * * @author Klaus Meffert * @since 3.2 */ public CultureMemoryCell storeMatrixMemory(int a_x, int a_y, Object a_value) { return m_memory.setMatrix(a_x, a_y, a_value); } /** * Reads a value from the internal matrix memory. * * @param a_x the first coordinate of the matrix (width) * @param a_y the second coordinate of the matrix (height) * @return read value * * @author Klaus Meffert * @since 3.2 */ public Object readMatrixMemory(int a_x, int a_y) { return m_memory.getMatrix(a_x, a_y).getCurrentValue(); } /** * Reads a value from the internal memory. * * @param a_name named index of the memory cell to read out * @return read value * * @author Klaus Meffert * @since 3.0 */ public Object readFromMemory(String a_name) { return m_memory.get(a_name).getCurrentValue(); } /** * @param a_name the name of the cell to evaluate * @return the value of a memory cell, if it exsists. Otherwise returns null. * * @author Klaus Meffert * @since 3.2 */ public Object readFromMemoryIfExists(String a_name) { CultureMemoryCell cell = null; try { cell = m_memory.get(a_name); } catch (IllegalArgumentException iex) { // Memory name not found: OK. // -------------------------- ; } if (cell == null) { return null; } return cell.getCurrentValue(); } /** * Stores a value in the internal indexed memory. * * @param a_index index of the cell * @param a_value the value to store * @return created or used memory cell * * @author Klaus Meffert * @since 3.2 */ public CultureMemoryCell storeIndexedMemory(int a_index, Object a_value) { return m_memory.set(a_index, a_value, -1, "noname"); } /** * Reads a value from the internal indexed memory. * * @param a_index index of the cell * @return read value (maybe null ) * * @author Klaus Meffert * @since 3.2 */ public Object readIndexedMemory(int a_index) { CultureMemoryCell cell = m_memory.get(a_index); if (cell == null) { return null; } else { return cell.getCurrentValue(); } } /** * Clears the memory. * * @author Klaus Meffert * @since 3.0 */ public void clearMemory() { m_memory.clear(); } public GPFitnessFunction getGPFitnessFunction() { return m_objectiveFunction; } /** * Set the fitness evaluator (deciding if a given fitness value is better * when it's higher or better when it's lower). * @param a_fitnessEvaluator the FitnessEvaluator to be used * * @author Klaus Meffert * @since 3.3.3 */ public void setFitnessEvaluator(IGPFitnessEvaluator a_fitnessEvaluator) { setGPFitnessEvaluator(a_fitnessEvaluator); } /** * Sets the fitness function to be used for this genetic algorithm. * The fitness function is responsible for evaluating a given * Chromosome and returning a positive integer that represents its * worth as a candidate solution. These values are used as a guide by the * natural to determine which Chromosome instances will be allowed to move * on to the next round of evolution, and which will instead be eliminated. * * @param a_functionToSet fitness function to be used * * @throws InvalidConfigurationException if the fitness function is null, or * if this Configuration object is locked. * * @author Klaus Meffert * @since 1.1 */ public synchronized void setFitnessFunction(GPFitnessFunction a_functionToSet) throws InvalidConfigurationException { verifyChangesAllowed(); // Sanity check: Make sure that the given fitness function isn't null. // ------------------------------------------------------------------- if (a_functionToSet == null) { throw new InvalidConfigurationException("The FitnessFunction instance must not be null."); } // Ensure that no other fitness function has been set in a different // configuration object within the same thread! // ----------------------------------------------------------------- checkProperty(PROPERTY_FITFUNC_INST, a_functionToSet, m_objectiveFunction, "Fitness function has already been set differently."); m_objectiveFunction = a_functionToSet; } /** * @return true: throw an error during evolution in case a situation is * detected where no function or terminal of a required type is declared * in the GPConfiguration; false: don't throw an error but try a completely * different combination of functions and terminals * * @author Klaus Meffert */ public boolean isStrictProgramCreation() { return m_strictProgramCreation; } /** * @param a_strict true: throw an error during evolution in case a situation * is detected where no function or terminal of a required type is declared * in the GPConfiguration; false: don't throw an error but try a completely * different combination of functions and terminals * * @author Klaus Meffert */ public void setStrictProgramCreation(boolean a_strict) { m_strictProgramCreation = a_strict; } public int getProgramCreationMaxtries() { return m_programCreationMaxTries; } public void setProgramCreationMaxTries(int a_maxtries) { m_programCreationMaxTries = a_maxtries; } /** * @return the fitness evaluator set * * @author Klaus Meffert * @since 3.0 */ public IGPFitnessEvaluator getGPFitnessEvaluator() { return m_fitnessEvaluator; } /** * Validates a_node in the context of a_chrom. Considers the recursion level * (a_recursLevel), the type needed (a_type) for the node, the functions * available (a_functionSet) and the depth of the whole chromosome needed * (a_depth), and whether grow mode is used (a_grow is true) or not. * * @param a_chrom the chromosome that will contain the node, if valid * @param a_node the node selected and to be validated * @param a_rootNode root node of the node to be validated (may be null) * @param a_tries number of times the validator has been called, useful for * stopping by returning true if the number exceeds a limit * @param a_num the chromosome's index in the individual of this chromosome * @param a_recurseLevel level of recursion * @param a_type the return type of the node needed * @param a_functionSet the array of available functions * @param a_depth the needed depth of the program chromosome * @param a_grow true: use grow mode, false: use full mode * @param a_childIndex index of the child in the parent node to which it * belongs (-1 if node is root node) * @param a_fullProgram true: whole program is available in a_chrom * * @return true: node is valid; false: node is invalid * * @author Klaus Meffert * @since 3.0 */ public boolean validateNode(ProgramChromosome a_chrom, CommandGene a_node, CommandGene a_rootNode, int a_tries, int a_num, int a_recurseLevel, Class a_type, CommandGene[] a_functionSet, int a_depth, boolean a_grow, int a_childIndex, boolean a_fullProgram) { INodeValidator nodeValidator = getNodeValidator(); if (nodeValidator == null) { return true; } return nodeValidator.validate(a_chrom, a_node, a_rootNode, a_tries, a_num, a_recurseLevel, a_type, a_functionSet, a_depth, a_grow, a_childIndex, a_fullProgram); } /** * Sets the node validator. Also see method validateNode. * * @param a_nodeValidator sic * * @author Klaus Meffert * @since 3.0 */ public void setNodeValidator(INodeValidator a_nodeValidator) { m_nodeValidator = a_nodeValidator; } /** * @return the node validator set * * @author Klaus Meffert * @since 3.0 */ public INodeValidator getNodeValidator() { return m_nodeValidator; } /** * Sets the validator for checking single nodes. * * @param a_singleNodeValidator sic * * @author Klaus Meffert * @since 3.6 */ public void setSingleNodeValidator(ISingleNodeValidator a_singleNodeValidator) { m_singleNodeValidator = a_singleNodeValidator; } /** * @return the validator set for single node checking * * @author Klaus Meffert * @since 3.6 */ public ISingleNodeValidator getSingleNodeValidator() { return m_singleNodeValidator; } /** * Compares this entity against the specified object. * * @param a_other the object to compare against * @return true: if the objects are the same, false otherwise * * @author Klaus Meffert * @since 3.1 */ public boolean equals(Object a_other) { try { return compareTo(a_other) == 0; } catch (ClassCastException cex) { return false; } } public int compareTo(Object a_other) { if (a_other == null) { return 1; } else { GPConfiguration other = (GPConfiguration) a_other; return new CompareToBuilder().append(m_objectiveFunction, other.m_objectiveFunction) .append(m_crossoverProb, other.m_crossoverProb) .append(m_reproductionProb, other.m_reproductionProb) .append(m_newChromsPercent, other.m_newChromsPercent) .append(m_maxCrossoverDepth, other.m_maxCrossoverDepth) .append(m_maxInitDepth, other.m_maxInitDepth) .append(m_selectionMethod.getClass(), other.m_selectionMethod.getClass()) .append(m_crossMethod.getClass(), other.m_crossMethod.getClass()) .append(m_programCreationMaxTries, other.m_programCreationMaxTries) .append(m_strictProgramCreation, other.m_strictProgramCreation) .append(m_fitnessEvaluator.getClass(), other.m_fitnessEvaluator.getClass()).toComparison(); } } /** * * @return see ProgramChromosome.growOrFull(...) and GPGenotype.evolve() * * @author Klaus Meffert * @since 3.2 */ public boolean isMaxNodeWarningPrinted() { return m_warningPrinted; } /** * See ProgramChromosome.growOrFull(...) and GPGenotype.evolve(). * * @author Klaus Meffert * @since 3.2 */ public void flagMaxNodeWarningPrinted() { m_warningPrinted = true; } /** * * @param a_program IGPProgram * * @author Klaus Meffert * @since 3.2 */ public void setPrototypeProgram(IGPProgram a_program) { m_prototypeProgram = a_program; } /** * @return prototype program set (maybe null if not setted previously) * * @author Klaus Meffert * @since 3.2 */ public IGPProgram getPrototypeProgram() { return m_prototypeProgram; } /** * @return capacity of the memory in cells * * @author Klaus Meffert * @since 3.2 */ public int getMemorySize() { return m_memory.size(); } public GPProgramInfo readProgramCache(GPProgram a_prog) { GPProgramInfo pci = new GPProgramInfo(a_prog, true); pci.setFound(false); return (GPProgramInfo) m_programCache.get(pci.getToStringNorm()); } public GPProgramInfo putToProgramCache(GPProgram a_prog) { GPProgramInfo pci = new GPProgramInfo(a_prog, true); return (GPProgramInfo) m_programCache.put(pci.getToStringNorm(), pci); } public boolean isUseProgramCache() { return m_useProgramCache; } public void setUseProgramCache(boolean a_useCache) { m_useProgramCache = a_useCache; } /** * Stores a Variable. * * @param a_var the Variable to store * * @author Klaus Meffert * @since 3.2 */ public void putVariable(Variable a_var) { m_variables.put(a_var.getName(), a_var); } /** * @param a_varName name of variable to retrieve * @return Variable instance or null, if not found * * @author Klaus Meffert * @since 3.2 */ public Variable getVariable(String a_varName) { return (Variable) m_variables.get(a_varName); } /** * @return deep clone of this instance * * @author Klaus Meffert * @since 3.2 */ public Object clone() { return newInstanceGP(getId(), getName()); } /** * Creates a new GPConfiguration instance by cloning. Allows to preset the * ID and the name. * * @param a_id new ID for clone * @param a_name new name for clone * @return deep clone of this instance * * @author Klaus Meffert * @since 3.2 */ public GPConfiguration newInstanceGP(String a_id, String a_name) { try { GPConfiguration result = new GPConfiguration(getName()); // Clone JGAPFactory first because it helps in cloning other objects. // ------------------------------------------------------------------ if (m_factory instanceof ICloneable) { result.m_factory = (IJGAPFactory) ((ICloneable) m_factory).clone(); } else { // We must fallback to a standardized solution. // -------------------------------------------- m_factory = new JGAPFactory(false); result.m_factory = (IJGAPFactory) ((JGAPFactory) m_factory).clone(); } if (result.m_factory == null) { throw new IllegalStateException("JGAPFactory must not be null!"); } if (m_objectiveFunction != null) { result.m_objectiveFunction = m_objectiveFunction; } int popSize = getPopulationSize(); if (popSize > 0) { result.setPopulationSize(popSize); } result.m_crossoverProb = m_crossoverProb; result.m_reproductionProb = m_reproductionProb; result.m_newChromsPercent = m_newChromsPercent; result.m_functionProb = m_functionProb; result.m_maxCrossoverDepth = m_maxCrossoverDepth; result.m_maxInitDepth = m_maxInitDepth; result.m_minInitDepth = m_minInitDepth; result.m_strictProgramCreation = m_strictProgramCreation; result.m_programCreationMaxTries = m_programCreationMaxTries; result.m_selectionMethod = (INaturalGPSelector) doClone(m_selectionMethod); result.m_crossMethod = (CrossMethod) doClone(m_crossMethod); result.m_fitnessEvaluator = (IGPFitnessEvaluator) doClone(m_fitnessEvaluator); result.m_nodeValidator = (INodeValidator) doClone(m_nodeValidator); result.m_useProgramCache = m_useProgramCache; result.m_verify = m_verify; result.m_variables = m_variables; // Configurable data. // ------------------ // result.m_config = new ConfigurationConfigurable(); // Identificative data. // -------------------- result.setName(a_name); result.setId(a_id); result.makeThreadKey(); // Must be called after m_id is set return result; } catch (Throwable t) { throw new CloneException(t); } } /** * @return the JGAP factory registered * * @author Klaus Meffert * @since 3.2 */ public IJGAPFactory getJGAPFactory() { return m_factory; } /** * When deserializing, do specific initializations. * * @param a_inputStream the ObjectInputStream provided for deserialzation * * @throws IOException * @throws ClassNotFoundException * * @author Klaus Meffert * @since 3.2 */ private void readObject(ObjectInputStream a_inputStream) throws IOException, ClassNotFoundException { //always perform the default de-serialization first a_inputStream.defaultReadObject(); try { init(false); } catch (InvalidConfigurationException iex) { iex.printStackTrace(); throw new IOException(iex.toString()); } } /** * * @param a_strategy IGPInitStrategy * * @author Klaus Meffert * @since 3.2.2 */ public void setInitStrategy(IGPInitStrategy a_strategy) { m_initStrategy = a_strategy; } /** * * @return IGPInitStrategy * * @author Klaus Meffert * @since 3.2.2 */ public IGPInitStrategy getInitStrategy() { return m_initStrategy; } /** * @param a_verify true: verify GP programs for correctness (i.e. is fitness * computation possible without exception?) * * @author Klaus Meffert * @since 3.3.4 */ public void setVerifyPrograms(boolean a_verify) { m_verify = a_verify; } /** * @return true: verify GP programs for correctness (i.e. is fitness * computation possible without exception?) * * @author Klaus Meffert * @since 3.3.4 */ public boolean isVerifyPrograms() { return m_verify; } /** * Decide whether to clone command genes when creating a new GP program in * ProgramChromosome. * * @param a_noCommandGeneCloning boolean * * @author Klaus Meffert * @since 3.4.3 */ public void setNoCommandGeneCloning(boolean a_noCommandGeneCloning) { m_noCommandGeneCloning = a_noCommandGeneCloning; } /** * @return true: do not clone command genes when creating a new GP program in * ProgramChromosome * * @author Klaus Meffert * @since 3.4.3 */ public boolean isNoCommandGeneCloning() { return m_noCommandGeneCloning; } }