int[] array mutation operator

114 views
Skip to first unread message

pau

unread,
Mar 20, 2012, 7:11:12 AM3/20/12
to watch...@googlegroups.com
Hello all.
I am trying to run example with WatchMaker framework, using array of primitive integers as population. What class should I use as mutation operator?

...
// Create a pipeline that applies cross-over then mutation.
List<EvolutionaryOperator<int[]>> operators = new LinkedList<EvolutionaryOperator<int[]>>();
operators.add(/* Here should come IntArrayMutation() or something like that */);
operators.add(new IntArrayCrossover())
EvolutionaryOperator<int[]> pipeline = new EvolutionPipeline<int[]>(operators);
FitnessEvaluator<int[]> fitnessEvaluator = new IntArrayEvaluator();
SelectionStrategy<Object> selection = new RouletteWheelSelection();
Random rng = new MersenneTwisterRNG();
EvolutionEngine<int[]> engine = new GenerationalEvolutionEngine<int[]>(factory, pipeline, fitnessEvaluator, selection, rng);
...

Thank you very much in advance.

Daniel Dyer

unread,
Mar 20, 2012, 12:22:31 PM3/20/12
to watch...@googlegroups.com
On Tue, 20 Mar 2012 11:11:12 -0000, pau <alexey....@gmail.com> wrote:

> Hello all.
> I am trying to run example with WatchMaker framework, using array of
> primitive integers as population. What class should I use as mutation
> operator?
>
> ...
> // Create a pipeline that applies cross-over then mutation.
> List<EvolutionaryOperator<int[]>> operators =

> newLinkedList<EvolutionaryOperator<
> int[]>>();
> operators.add(/* Here should come *IntArrayMutation()* or something like
> that */);

You will probably have to implement your own mutation operator depending
on exactly how you intend to mutate the integers (there isn't currently a
generic off-the-shelf implementation for you to use). You just need to
implement the single method of the EvolutionaryOperator interface.

Dan.

--
Daniel Dyer

pau

unread,
Mar 21, 2012, 1:32:39 AM3/21/12
to watch...@googlegroups.com

You will probably have to implement your own mutation operator depending  
on exactly how you intend to mutate the integers (there isn't currently a  
generic off-the-shelf implementation for you to use).  You just need to  
implement the single method of the EvolutionaryOperator interface.

Dan.

--
Daniel Dyer

Thank you very much for answering, Dan.
I am doing like this:
...
wmOperators = new LinkedList<>();
wmOperators.add(new IntArrayCrossover());
wmOperators.add(new Replacement<int[]>(wmFactory, new Probability(0.2d)));
wmPipeline = new EvolutionPipeline<>(wmOperators);
...
is that OK?

Daniel Dyer

unread,
Mar 22, 2012, 10:17:44 AM3/22/12
to watch...@googlegroups.com
On Wed, 21 Mar 2012 05:32:39 -0000, pau <alexey....@gmail.com> wrote:

> Thank you very much for answering, Dan.
> I am doing like this:
> ...
> wmOperators = new LinkedList<>();
> wmOperators.add(new IntArrayCrossover());
> wmOperators.add(new Replacement<int[]>(wmFactory, new
> Probability(0.2d)));
> wmPipeline = new EvolutionPipeline<>(wmOperators);
> ...
> is that OK?

It depends on exactly what you are trying to achieve but I would assume
that you'd normally want a proper mutation operator in there. The
Replacement operator is not the same thing because it does not preserve
any part of the original candidate, it replaces it with a completely new
one. If you want to perform mutation on an array of ints then you'll need
to write your own mutation operator that implements the kind of mutation
that you need. It should be pretty straightforward, just create a class
that implements EvolutionaryOperator:

class IntArrayMutation implements EvolutionaryOperator<int[]>
{
public List<int[]> apply(List<int[]> selectedCandidates, Random rng)
{
List<int[]> results = new
ArrayList<int[]>(selectedCandidates.size());
for (int[] candidate : selectedCandidates)
{
int[] copy = candidate.clone();

// TO DO: Modify the cloned int array here, using the RNG for
any
// required random values.

results.add(copy);
}
return results;
}
}


Dan.

--
Daniel Dyer

pau

unread,
Mar 24, 2012, 2:50:01 AM3/24/12
to watch...@googlegroups.com
Hello, Dan.

Here it is the IntArrayMutation evolutionary operator:

public class IntArrayMutation implements EvolutionaryOperator<int[]> {
    
    Probability probapility;
    int min, max;
    
    public IntArrayMutation (int min, int max, Probability probability) {
        this.min = min;
        this.max = max;
        this.probapility = probability;
    }

    @Override
    public List<int[]> apply(List<int[]> selectedCandidates, Random rng) {
        List<int[]> result = new ArrayList<>(selectedCandidates.size());
        for (int[] candidate : selectedCandidates) {
            int[] copy = candidate.clone();
            double r = rng.nextDouble();
            if (r <= probapility.doubleValue()) {
                int index = rng.nextInt(candidate.length);
                int value = rng.nextInt(max) + min;
                candidate[index] = value;
            }
            result.add(copy);
        }
        return result;
    }
}

Here is the code:
...
operators = new LinkedList<>();
operators.add(new IntArrayCrossover());
//operators.add(new Replacement<int[]>(factory, new Probability(0.2d)));
operators.add(new IntArrayMutation(rangeMin, rangeMax, new Probability(0.2d)));
pipeline = new EvolutionPipeline<>(operators);
...
engine = new GenerationalEvolutionEngine<>(factory, pipelinenew CachingFitnessEvaluator<>(evaluator), new TournamentSelection(new Probability(0.9d)), new MersenneTwisterRNG());
int[] result = engine.evolve(populationSize, 5, new Stagnation(150, false));
...

Here is the result:
Time spent: 01:34.189, fitness:     540,0, generations:189

But when I use Replacement instead of IntArrayMutation, the result is:
Time spent: 02:25.326, fitness:     100,0, generations:291

Seems like Replacement is better ... Or am I doing something wrong?




Reply all
Reply to author
Forward
0 new messages