RepeatedMutator.java

package net.bmahe.genetics4j.core.mutation;

import java.util.Objects;
import java.util.random.RandomGenerator;

import org.apache.commons.lang3.Validate;

import net.bmahe.genetics4j.core.Genotype;
import net.bmahe.genetics4j.core.spec.mutation.RepeatedMutation;

/**
 * Applies a child mutator repeatedly, passing each mutation result to the next invocation.
 */
public class RepeatedMutator implements Mutator {

	private final RandomGenerator randomGenerator;
	private final RepeatedMutation repeatedMutation;
	private final Mutator childMutator;

	public RepeatedMutator(final RandomGenerator _randomGenerator,
			final RepeatedMutation _repeatedMutation,
			final Mutator _childMutator) {
		this.randomGenerator = Objects.requireNonNull(_randomGenerator);
		this.repeatedMutation = Objects.requireNonNull(_repeatedMutation);
		this.childMutator = Objects.requireNonNull(_childMutator);
	}

	@Override
	public Genotype mutate(final long generation, final Genotype original) {
		Validate.isTrue(generation >= 0);
		Objects.requireNonNull(original);

		final int numRepetitions = numberOfRepetitions();
		Genotype mutated = original;
		for (int i = 0; i < numRepetitions; i++) {
			mutated = childMutator.mutate(generation, mutated);
		}

		return mutated;
	}

	private int numberOfRepetitions() {
		final int minRepetitions = repeatedMutation.minRepetitions();
		final int maxRepetitions = repeatedMutation.maxRepetitions();
		if (minRepetitions == maxRepetitions) {
			return minRepetitions;
		}

		return (int) randomGenerator.nextLong(minRepetitions, (long) maxRepetitions + 1L);
	}
}