Individual representations

Genetic Engine currently supports 4 individual representations:

  • Tree-based representation, also known as Context-Free Grammars GP (CFG-GP)[1]

  • Grammatical Evolution (GE)[2]

  • Structured GE (SGE)[3]

  • Dynamic SGE (dSGE)[4]

The representation can be chosen by the user. There are many discussions on which representation performs better as a search algorithm (fitness progression will differ across algorithms). Genetic Engine uses the same method for tree generation in CFG-GP and genotype-to-phenotype mapping in GE, SGE and dSGE, making it individual-representation independent on the implementation side. Still, we aim to implement performance enhancements on trees, benefitting the performance of CFG-GP, both on the time performance side (such as detailed in [5]), as on the algorithm side.

Tree-based

class geneticengine.representations.tree.treebased.TreeBasedRepresentation(grammar, max_depth, initialization_method=pi_grow_method)

This class represents the tree representation of an individual.

In this approach, the genotype and the phenotype are exactly the same.

Parameters:

Grammatical Evolution

class geneticengine.representations.grammatical_evolution.ge.GrammaticalEvolutionRepresentation(grammar, max_depth, gene_length=256, initialization_mode=pi_grow_method)

Abstract base class for generic types.

A generic type is typically declared by inheriting from this class parameterized with one or more type variables. For example, a generic mapping type might be defined as:

class Mapping(Generic[KT, VT]):
    def __getitem__(self, key: KT) -> VT:
        ...
    # Etc.

This class can then be used as follows:

def lookup_name(mapping: Mapping[KT, VT], key: KT, default: VT) -> VT:
    try:
        return mapping[key]
    except KeyError:
        return default
Parameters:
  • grammar (Grammar) – The grammar to use in the mapping

  • max_depth (int) – the maximum depth when performing the mapping

  • initialization_mode (InitializationMethodType) – method to create individuals in the mapping (e.g., pi_grow, full, grow)

  • gene_length (int)

Structured Grammatical Evolution

class geneticengine.representations.grammatical_evolution.structured_ge.StructuredGrammaticalEvolutionRepresentation(grammar, max_depth, gene_length=256, initialization_mode=pi_grow_method)

This version uses a list of lists of integers to represent individuals, based on non-terminal symbols.

Parameters:
  • grammar (Grammar) – The grammar to use in the mapping

  • max_depth (int) – the maximum depth when performing the mapping

  • initialization_mode (InitializationMethodType) – method to create individuals in the mapping (e.g., pi_grow, full, grow)

  • gene_length (int)

Dynamic Structured Grammatical Evolution

class geneticengine.representations.grammatical_evolution.dynamic_structured_ge.DynamicStructuredGrammaticalEvolutionRepresentation(grammar, max_depth, gene_length=256, initialization_mode=pi_grow_method)

This version uses a list of lists of integers to represent individuals, based on non-terminal symbols.

Parameters:
  • grammar (Grammar) – The grammar to use in the mapping

  • max_depth (int) – the maximum depth when performing the mapping

  • initialization_mode (InitializationMethodType) – method to create individuals in the mapping (e.g., pi_grow, full, grow)

  • gene_length (int)

Stack-based Grammatical Evolution

class geneticengine.representations.stackgggp.StackBasedGGGPRepresentation(grammar, max_depth, gene_length=256)

This representation uses a list of integers to guide the generation of trees in the phenotype.

Parameters:

Custom Representations

To create a custom representation, you just need to subclass the following abstract class:

class geneticengine.representations.api.Representation

Abstract base class for generic types.

A generic type is typically declared by inheriting from this class parameterized with one or more type variables. For example, a generic mapping type might be defined as:

class Mapping(Generic[KT, VT]):
    def __getitem__(self, key: KT) -> VT:
        ...
    # Etc.

This class can then be used as follows:

def lookup_name(mapping: Mapping[KT, VT], key: KT, default: VT) -> VT:
    try:
        return mapping[key]
    except KeyError:
        return default

To support Genetic Programming, you also need to implement:

class geneticengine.representations.api.RepresentationWithMutation

Abstract base class for generic types.

A generic type is typically declared by inheriting from this class parameterized with one or more type variables. For example, a generic mapping type might be defined as:

class Mapping(Generic[KT, VT]):
    def __getitem__(self, key: KT) -> VT:
        ...
    # Etc.

This class can then be used as follows:

def lookup_name(mapping: Mapping[KT, VT], key: KT, default: VT) -> VT:
    try:
        return mapping[key]
    except KeyError:
        return default
class geneticengine.representations.api.RepresentationWithCrossover

Abstract base class for generic types.

A generic type is typically declared by inheriting from this class parameterized with one or more type variables. For example, a generic mapping type might be defined as:

class Mapping(Generic[KT, VT]):
    def __getitem__(self, key: KT) -> VT:
        ...
    # Etc.

This class can then be used as follows:

def lookup_name(mapping: Mapping[KT, VT], key: KT, default: VT) -> VT:
    try:
        return mapping[key]
    except KeyError:
        return default

References