1. Evolutionary Algorithm Bases

The base module provides basic structures to build evolutionary algorithms.

1.1. Container Types

As of version 0.5.0, eap does not provide base types that wrap python base types, instead it is possible to create your own types that inherits from whatever type is more convenient or appropriate, for example, list, array, set, dict, etc. As most of those types are initialized using an iterable, the creator allows to create these objects using internal generators in order to produce objects with different content. See the creator module for more information.

class eap.base.Tree([content])

Basic N-ary tree class.

classmethod convertNode(node)

Convert node into the proper object either a Tree or a Node.

getstate()

Return the state of the Tree as a list of arbitrary elements. It is mainly used for pickling a Tree object.

height

Return the height of the tree.

The height of a tree is the length of the path from the root to the deepest node in the tree. A (rooted) tree with only one node (the root) has a height of zero.

root

Return the root element of the tree.

The root node of a tree is the node with no parents. There is at most one root node in a rooted tree.

searchSubtreeBF(index)

Search the subtree with the corresponding index based on a breadth-first search.

searchSubtreeDF(index)

Search the subtree with the corresponding index based on a depth-first search.

setSubtreeBF(index, subtree)

Replace the subtree with the corresponding index by subtree based on a breadth-first search.

setSubtreeDF(index, subtree)

Replace the tree with the corresponding index by subtree based on a depth-first search.

size

Return the number of nodes in the tree.

The size of a node is the number of descendants it has including itself.

1.2. Fitness

class eap.base.Fitness(values=())

The fitness is a measure of quality of a solution.

Fitnesses may be compared using the >, <, >=, <=, ==, !=. The comparison of those operators is made lexicographically. Maximization and minimization are taken care off by a multiplication between the weights and the fitness values. The comparison can be made between fitnesses of different size, if the fitnesses are equal until the extra elements, the longer fitness will be superior to the shorter.

isDominated(other)

In addition to the comparaison operators that are used to sort lexically the fitnesses, this method returns True if this fitness is dominated by the other fitness and False otherwise. The weights are used to compare minimizing and maximizing fitnesses. If there is more fitness values than weights, the las weight get repeated until the end of the comparaison.

valid

Asses if a fitness is valid or not.

values

Fitness values. Use directly individual.fitness.values = values in order to set the fitness and del individual.fitness.values in order to clear (invalidate) the fitness. The (unweighted) fitness can be directly accessed via individual.fitness.values.

weights = ()

The weights are used in the fitness comparison. They are shared among all fitnesses of the same type. This member is not meant to be manipulated since it may influence how fitnesses are compared and may result in undesirable effects. However if you wish to manipulate it, in order to make the change effective to all fitnesses of the same type, use FitnessType.weights = new_weights or self.__class__.weights = new_weights or from an individual ind.fitness.__class__.weights = new_weights.

wvalues = ()

Contains the weighted values of the fitness, the multiplication with the weights is made when the values are set via the property values. Multiplication is made on setting of the values for efficiency.

Generaly it is unnecessary to manipulate wvalues as it is an internal attribute of the fitness used in the comparison operators.

1.3. Creator

The creator module is the heart and soul of EAP, it allows to create, at runtime, classes that will fulfill the needs of your evolutionary algorithms.

eap.creator.create(name, base[, attribute[, ...]])

The function create() does create a new class named name inheriting from base in the creator module. The new class can have attributes defined by the subsequent keyworded arguments passed to the function create. If the argument is callable, it is automatically called in the initialisation of an instance of this class and the returned object is added as an attribute of the class’ instance. Otherwise, if the argument is not callable, (for example an int), it is added as a “static” attribute of the class.

For example, using

creator("MyType", object, value=4, data=lambda: random.random())

is the same as defining in the module eap.creator

class MyType(object):
    value = 4
    def __init__(self):
        self.data = random.random()

1.4. Population, Individual and Other Structures

All application specific structures may be built using the create() function and types defined in python or the base module. Here are some simple recipes to build very simple types.

1.4.1. Fitness

As described earlier, the eap.base.Fitness instantiate by default a minimizing fitness. This can be changed using the creator and its eap.creator.create() function. A maximizing fitness can be created using

create("FitnessMax", base.Fitness, weights=(1.0,))

1.4.2. Individual

There is only one rule when building an individual, it must contain a fitness attribute. The following all produce valid individuals that are suited for most evolutionary algorithms.

1.4.2.1. Individual List

The individual list is suited for binary, integer, float and even funky individuals. It may contain any type and/or any type mix that is needed. The IndividualList type is created with

create("IndividualList", list, fitness=creator.FitnessMax)

and an individual of size 5 is instantiated with

content = [random.random() for i in xrange(5)]
ind = creator.IndividualList(content)

Note

For individuals containing only a single numeric type, it may be more suited to use the array base class, as the copy operation is way more efficient.

1.4.2.2. Individual Indices

The individual indices is almost the same as the individual list, except for its content. Here we will use the maximizing fitness describes earlier

create("IndividualIndices", list, fitness=creator.FitnessMax)

and an individual indices of size 5 is instantiated with

content = random.sample(xrange(5), 5)
ind = creator.IndividualIndices(content)

1.4.2.3. Individual Tree

The individual tree is a bit harder to create. We first must define a primitive set and the operator we need in our post-fix trees.

pset = gp.PrimitiveSet("MAIN", 1)
pset.addPrimitive(operator.add, 2)
pset.addPrimitive(operator.sub, 2)
pset.addPrimitive(operator.mul, 2)

Then it is just as easy as other types, the tree class may be initialized from a iterable. The gp module contains some helper functions to build trees. For example, the generate_full() will produce a full tree.

creator.create("IndividualTree", gp.PrimitiveTree, fitness=creator.FitnessMax, pset=pset)
ind = creator.IndividualTree(gp.generate_full(pset=pset, min=3, max=5))

1.4.3. Population

A population is usually a list of individuals or sub-populations, it is no more complicated to create than an individual. When using a Toolbox, it is often not necessary to create a class Population, it is made here just to show how it would be created.

create("Population", list)

A population of 10 individuals of indices is instanciated using

ind_content = lambda: random.sample(xrange(5), 5)
pop_content = [creator.IndividualIndices(ind_content()) for i in xrange(10)]
pop = creator.Population(pop_content)

Note

A deme (sub-population) is no more than a population, it is created the same way as a population (or any other list type).

See also

The First Steps of Evolution shows how to combine the creator and the toolbox to initialize types.