Class ProgramChromosome<A>

All Implemented Interfaces:
Chromosome<ProgramGene<A>>, TreeChromosome<Op<A>,ProgramGene<A>>, BaseSeq<ProgramGene<A>>, Factory<Chromosome<ProgramGene<A>>>, Verifiable, Serializable, Iterable<ProgramGene<A>>, Function<A[],A>, RandomAccess

public class ProgramChromosome<A> extends AbstractTreeChromosome<Op<A>,ProgramGene<A>> implements Function<A[],A>, Serializable
Holds the nodes of the operation tree.
final int depth = 6;
final ISeq<Op<Double>> operations = ISeq.of(...);
final ISeq<Op<Double>> terminals = ISeq.of(...);
final ProgramChromosome<Double> ch = ProgramChromosome.of(
    depth,
    // If the program has more than 200 nodes, it is marked as "invalid".
    ch -> ch.length() <= 200,
    operations,
    terminals
);
Since:
3.9
Version:
4.1
See Also:
  • Constructor Details

    • ProgramChromosome

      protected ProgramChromosome(ISeq<ProgramGene<A>> program, Predicate<? super ProgramChromosome<A>> validator, ISeq<? extends Op<A>> operations, ISeq<? extends Op<A>> terminals)
      Create a new program chromosome from the given program genes. This constructor assumes that the given program is valid. Since the program validation is quite expensive, the validity check is skipped in this constructor.
      Parameters:
      program - the program. During the program evolution, newly created program trees have the same depth than this tree.
      validator - the chromosome validator. A typical validator would check the size of the tree and if the tree is too large, mark it at invalid. The validator may be null.
      operations - the allowed non-terminal operations
      terminals - the allowed terminal operations
      Throws:
      NullPointerException - if one of the given arguments is null
      IllegalArgumentException - if either the operations or terminals sequence is empty
  • Method Details

    • operations

      public ISeq<Op<A>> operations()
      Return the allowed operations.
      Returns:
      the allowed operations
      Since:
      5.0
    • terminals

      public ISeq<Op<A>> terminals()
      Return the allowed terminal operations.
      Returns:
      the allowed terminal operations
      Since:
      5.0
    • isValid

      public boolean isValid()
      Specified by:
      isValid in interface Chromosome<A>
      Specified by:
      isValid in interface Verifiable
      Overrides:
      isValid in class AbstractChromosome<ProgramGene<A>>
    • apply

      public A apply(A[] args)
      Evaluates the root node of this chromosome.
      Specified by:
      apply in interface Function<A[],A>
      Parameters:
      args - the input variables
      Returns:
      the evaluated value
      Throws:
      NullPointerException - if the given variable array is null
      See Also:
    • eval

      @SafeVarargs public final A eval(A... args)
      Evaluates the root node of this chromosome.
      Parameters:
      args - the function arguments
      Returns:
      the evaluated value
      Throws:
      NullPointerException - if the given variable array is null
      See Also:
    • newInstance

      Specified by:
      newInstance in interface Chromosome<A>
    • newInstance

      Specified by:
      newInstance in interface Factory<A>
    • of

      public static <A> ProgramChromosome<A> of(Tree<? extends Op<A>,?> program, Predicate<? super ProgramChromosome<A>> validator, ISeq<? extends Op<A>> operations, ISeq<? extends Op<A>> terminals)
      Create a new chromosome from the given operation tree (program).
      Type Parameters:
      A - the operation type
      Parameters:
      program - the operation tree
      validator - the chromosome validator. A typical validator would check the size of the tree and if the tree is too large, mark it at invalid. The validator may be null.
      operations - the allowed non-terminal operations
      terminals - the allowed terminal operations
      Returns:
      a new chromosome from the given operation tree
      Throws:
      NullPointerException - if one of the given arguments is null
      IllegalArgumentException - if the given operation tree is invalid, which means there is at least one node where the operation arity and the node child count differ.
    • of

      public static <A> ProgramChromosome<A> of(Tree<? extends Op<A>,?> program, ISeq<? extends Op<A>> operations, ISeq<? extends Op<A>> terminals)
      Create a new chromosome from the given operation tree (program).
      Type Parameters:
      A - the operation type
      Parameters:
      program - the operation tree
      operations - the allowed non-terminal operations
      terminals - the allowed terminal operations
      Returns:
      a new chromosome from the given operation tree
      Throws:
      NullPointerException - if one of the given arguments is null
      IllegalArgumentException - if the given operation tree is invalid, which means there is at least one node where the operation arity and the node child count differ.
    • of

      public static <A> ProgramChromosome<A> of(int depth, Predicate<? super ProgramChromosome<A>> validator, ISeq<? extends Op<A>> operations, ISeq<? extends Op<A>> terminals)
      Create a new program chromosome with the defined depth. This method will create a full program tree.
      Type Parameters:
      A - the operation type
      Parameters:
      depth - the depth of the created program tree
      validator - the chromosome validator. A typical validator would check the size of the tree and if the tree is too large, mark it at invalid. The validator may be null.
      operations - the allowed non-terminal operations
      terminals - the allowed terminal operations
      Returns:
      a new program chromosome from the given (flattened) program tree
      Throws:
      NullPointerException - if one of the parameters is null
      IllegalArgumentException - if the depth is smaller than zero
    • of

      public static <A> ProgramChromosome<A> of(int depth, ISeq<? extends Op<A>> operations, ISeq<? extends Op<A>> terminals)
      Create a new program chromosome with the defined depth. This method will create a full program tree.
      Type Parameters:
      A - the operation type
      Parameters:
      depth - the depth of the created (full) program tree
      operations - the allowed non-terminal operations
      terminals - the allowed terminal operations
      Returns:
      a new program chromosome from the given (flattened) program tree
      Throws:
      NullPointerException - if one of the parameters is null
      IllegalArgumentException - if the depth is smaller than zero
    • of

      public static <A> ProgramChromosome<A> of(ISeq<ProgramGene<A>> genes, Predicate<? super ProgramChromosome<A>> validator, ISeq<? extends Op<A>> operations, ISeq<? extends Op<A>> terminals)
      Create a new program chromosome from the given (flattened) program tree. This method doesn't make any assumption about the validity of the given operation tree. If the tree is not valid, it will repair it. This behaviour allows the safe usage of all existing alterers.
      final ProgramChromosome<Double> ch = ProgramChromosome.of(
          genes,
          // If the program has more that 200 nodes, it is marked as "invalid".
          ch -> ch.length() <= 200,
          operations,
          terminals
      );
      
      Type Parameters:
      A - the operation type
      Parameters:
      genes - the program genes
      validator - the chromosome validator to use
      operations - the allowed non-terminal operations
      terminals - the allowed terminal operations
      Returns:
      a new program chromosome from the given (flattened) program tree
      Throws:
      NullPointerException - if one of the parameters is null
    • of

      public static <A> ProgramChromosome<A> of(ISeq<ProgramGene<A>> genes, ISeq<? extends Op<A>> operations, ISeq<? extends Op<A>> terminals)