Package org.jgap.gp.impl

Source Code of org.jgap.gp.impl.GPConfiguration

/*
* 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.util.*;
import org.apache.commons.lang.builder.CompareToBuilder;
import org.jgap.*;
import org.jgap.impl.*;
import org.jgap.distr.*;
import org.jgap.event.*;
import org.jgap.gp.*;
import org.jgap.gp.terminal.Variable;
import org.jgap.util.ICloneable;
import org.jgap.util.CloneException;
import java.io.*;

/**
* 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.47 $";

  /**@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);

  /**@todo make 50 configurable*/
  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;

  /**
   * 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 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);
    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;
  }

  /**
   * 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;
  }

  /**
   * 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 retriebe
   * @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);
        /*@todo move popSize from super to here!*/
      }
      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;
      // 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;
  }

}
TOP

Related Classes of org.jgap.gp.impl.GPConfiguration

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.