Top-Down page - Bottom-up page - Programming hints - EO documentation


TOC : Introduction - Crossover - Mutation - Simple combinations - General Operators - General combinations

Variation Operators


Variation Operators
Variation operators modify individuals, or, equivalently, move them in the search space. They are almost always stochastic, i.e. they are based on random numbers, or equivalently, perform random modifications of their arguments. Variation operators are classified depending on the number of arguments they use and/or modify.

Variation operators involving two individuals are called crossover operators. They can either modify one of the parents according to the material of the other parent, or modify both parents. In EO, the former are called Binary operators and the latter Quadratic operators.
Variation operators involving one single individual are called mutation operators.
In EO you can also define and use variation operators that generate any number of offspring from any number of parents (sometimes termed orgy operators). They are called general operators.

Though most the historical evolutionary algorithms used at most one crossover and one mutation (see e.g. the Simple Genetic Algorithm in lesson1), the trend now in evolutionary computation is to combine operators, choosing at run-time and for each individual which operator to apply. This can be done in the framework of simple operators, combining for instance several mutations into a variation operator that chooses one of them according to user-defined preferences: such combinations are called in EO proportional combination of simple operators (see e.g. how to define and use such combined operators in the SGA of lesson2).

Finally, there are many other ways to combine different variation operators of different kind. Within EO, you can choose to apply many different types of operator to the population, either in turn (this is called sequential combination) or by randomly choosing among a set of operators at a given time (this is proportional combination, generalizing the one defined for simple operators). You can of course mix and interleave both approaches at will, and this is described as general combination of general operators.

EO implementation: all variation operators in EO derive from the base (abstract) class eoOp (as usual, click to see the inheritance diagram). blabla



Simple operators: Crossover

The characteristic of crossover operators is that they involve two parents. However, there are crossover operators that generate two parents, and some that generate one parent only, and both types are available in EO. The former type (2 --> 2) is termed quadratic crossover operator, and is implemanted in the eoQuadOp class; the latter type (2 --> 1) is termed binary operator and is implemanted in class eoBinOp. Both classes are, as usual, templatized by the type of individual they can handle (see documentation for eoBinOp and eoQuadOp).

Note: Whereas it is straightforward to create a binary crossover operator from a quadratic one (by discarding the changes on the second parent), the reverse might prove impossible (imagine a binary crossover that simply merges the parents material: there is no way to generate two new parents from that!).

Interfaces:
The general approach in EO about simple variation operators is to perform in-place modifications, i.e. modifying the arguments rather than generating new (modified) individuals. This results in the following interfaces for the functor objects eoBinOp and eoQuadOp:

void operator()(EOT & , const EOT &)         for eoBinOp (note the const)
void operator()(EOT & , EOT & )                       for eoQuadOp

which you could have guessed from the inheritance diagrams up to the eoBF abstract class. You can also guess that only the first argument will be modified by an oeBin object, while both arguments will be modified by an eoQuad object.

Using crossover operators:
Directly applying crossover operators is straightforward from the interface above:
eoBinOpDerivedClass<Indi> myBinOp(parameters);     //  use constructor to pass
eoQuadOpDerivedClass<Indi> myQuadOp(parameters);   //  any useful argument
Indi eo1= ..., eo2= ...;   // the candidates to crossover
myBinOp(eo1, eo2);         // will modify eo1 only
myQuadOp(eo1, eo2);        // will modify eo1 and eo2

However, you will hardly have to do so, as operators are used within other classes, and are applied systematically to whole sets of individuals (e.g. that have already been selected, in standard generational evolutionary algorithms).
Hence the way to use such operators will more likely ressemble, if you are using for instance an SGA, this (definition, usage). See also the different ways that are described below, encapsulating the operators into combined operators objects.
 

Writing a crossover operator:
There are only two things to modify in the template class definitions provided (apart from the name of the class you are creating!)



Simple operators: Mutation
Mutation operators modify one single individual. The corresponding EO class is called eoMonOp. and it si as usual templatized by the type of individual it can handle (see documentation for eoMonOp).

Interfaces:
The general approach in EO about simple variation operators is to perform in-place modifications, i.e. modifying the arguments rather than generating new (modified) individuals. This results in the following interface for the functor objects eoMonOp:

void operator()(EOT & )

which you could have guessed from the inheritance diagrams up to the eoUF abstract class.

Using mutation operators:
Directly applying mutation operators is straightforward from the interface above:
eoMonOpDerivedClass<Indi> myMutation(parameters); //pass parameters in constructor
Indi eo1 = ...;           // eo1 is candidate to mutation
myMutation(eo1);          // will modify eo1

However, you will hardly have to do so, as operators are used within other classes, and are applied systematically to whole sets of individuals (e.g. that have already been selected, in standard generational evolutionary algorithms).
Hence the way to use such operators will more likely ressemble, if you are using for instance an SGA, this (definition, usage). See also the different ways that are described below, encapsulating the operators into combined operators objects.

Writing a mutation operator:
There are only two things to modify in the template class definitions provided (apart from the name of the class you are creating!)



Combining simple operators: proportional combinations

The best thing to do is to go to the Lesson2 of the tutorial, where everything is explained.


General Operators
 


General Combinations:

There are two main ways to use and combine general operators in EO: the proportional combination, similar to what has been described for simple operators above, and the sequential combination, which amounts to apply all operators in turn to a bunch of individuals, each operator being applied with a specific probability.

Proportional combinations behave like a unique operator: when it is called upon a population of candidates, an eoProportionalOpContainer enters the following loop:

while there are individuals left in the candidate population

Sequential combinations behave like a unique operator: when it is called upon a population of candidates, an eoSequentialOpContainer enters the following loop:

for all operators it contains, apply the operator to the candidate population, that is

Remark:The eoSGATransform presented in Lesson2 can be viewed as a particular type of eoSequentialOpContainer. It was not coded that way in order to provide a gradual introduction to all concepts.
Exercise: write the code to perform an eoSGA using the eoOpContainer constructs.

Remark: there is actually a single list of individuals that is maintained through a clever mecahnism of mark, rewind and unmark, but that's a purely technical matter. If you are interested, go and check the eoOpContainer and the eoSequentialOpContainer code.
 

Adding operators to a container:
The basic function to add an operator to an eoOpContainer is the method add from class eoOpContainer.
It is similar to all other add methods in other Combined things in eo (as the simple eoProportionalCombinedXXXop described above, but also the eoCombinedContinue class or the eoCheckPoint class).
The syntax is straightforward, and it works with any of the operator classes defined above:

someOperatorType<Indi> myOperator;
eoXXXOpContainer<Indi> myOpContainer;
myOpContainer.add(myOperator, rate); // rate: double whose meaning depends on XXX

where XXX can be one of Proportional and Sequential.
However, the way rate will be used is highly dependent on the type of OpContainer your are creating there:



TOC : Introduction - Crossover - Mutation - Simple combinations - General Operators - General combinations

Top-Down page - Bottom-up page - Programming hints -EO documentation

Marc Schoenauer

Last modified: Fri Dec. 8 2000