On evolutionary operators

35 views
Skip to first unread message

Martin Waßmann

unread,
May 27, 2011, 10:04:33 AM5/27/11
to Watchmaker Framework for Evolutionary Computation
When implementing evolutionary operators, especially several mutation,
I found myself doing the same thing over and over again, and therefore
introduced a basic platform to realise mutations. As I think it'd be a
good addition to the framework (the idea, not the code), I'm sharing
it with you. (See code below!)

As the EvolutionaryOperator is defined on the whole population, each
mutation operator starts with creating a new empty population, then
iterating over the candidates and mutating them according to a
probability. Therefore I separated the common behaviour (of all
mutations) from the mutation specific, resulting in a class
MutationOperator, implementing the EvoOp interface, and an Interface
MutationStrategy. In order to implement a new mutation operator, one
would just have to implement the MutationStrategy Interface and
instantiate the MutationOperator Class with the new MutationStrategy
implementation.

The main advantage of this approach is, that the framework provides a
platform to easily realise mutations, rather than everyone inventing
something similar on its own, and that the framework would have full
control of the program flow. It'd be quite easy (as mutations a
generally independent from each other) to exploit parallelism in the
MutationOperators apply-Method. The same could of course be done for
the other large group of operators, the recombinations.

Another advantage of the MutationStrategy Interface is, that it'd be
quite easy to introduce combinators, aggregating several mutations,
e.g. randomly selecting a mutation from a set of available mutations.
(These combinators could be general purpose (and so part of the
framework), when realised as generics.)

It's just a thought.

Regards,
Martin

public interface MutationStrategy<T> {
public T mutate( T individual, Random rng );
}

public class MutationOperator<T> implements EvolutionaryOperator<T> {

protected final double probability;
protected final MutationStrategy<T> strategy;

public MutationOperator( MutationStrategy<T> strategy, double
probability ) {
this.probability = probability;
this.strategy = strategy;
}

@Override
public List<T> apply( List<T> selectedCandidates, Random rng) {
final List<T> mutatedIndividuals = new LinkedList<T>();

for( T candidate : selectedCandidates ) {
if( rng.nextDouble() < this.probability ) {
mutatedIndividuals.add(this.strategy.mutate(candidate, rng));
}
else {
mutatedIndividuals.add(candidate);
}
}

return mutatedIndividuals;
}
}

public class RandomMutationSelector<T> implements MutationStrategy<T>
{

protected final List<MutationStrategy<T>> strategies;

public RandomMutationSelector( Collection<MutationStrategy<T>>
strategies ) {
this.strategies = new ArrayList<MutationStrategy<T>>(strategies);
}

@Override
public T mutate(T individual, Random rng) {
return
this.strategies.get(rng.nextInt(this.strategies.size())).mutate(individual,
rng);
};
}

Daniel Dyer

unread,
May 28, 2011, 7:30:12 PM5/28/11
to Watchmaker Framework for Evolutionary Computation
Martin, thanks for this. It looks like a sensible approach to me.
I'll take a look at integrating this next time I get a chance to work
on the code.

Thanks,

Dan.
Reply all
Reply to author
Forward
0 new messages