RepeatedMutation.java

package net.bmahe.genetics4j.core.spec.mutation;

import java.util.Objects;

import org.apache.commons.lang3.Validate;
import org.immutables.value.Value;

/**
 * Applies another mutation policy repeatedly.
 *
 * <p>The number of repetitions is selected uniformly between {@link #minRepetitions()} and
 * {@link #maxRepetitions()}, inclusive, for each genotype. Equal bounds define a fixed number of repetitions.
 */
@Value.Immutable
public abstract class RepeatedMutation implements MutationPolicy {

	@Value.Parameter
	public abstract int minRepetitions();

	@Value.Parameter
	public abstract int maxRepetitions();

	@Value.Parameter
	public abstract MutationPolicy mutationPolicy();

	@Value.Check
	protected void check() {
		Validate.isTrue(minRepetitions() > 0);
		Validate.isTrue(maxRepetitions() >= minRepetitions());
		Objects.requireNonNull(mutationPolicy());
	}

	public static class Builder extends ImmutableRepeatedMutation.Builder {
	}

	public static Builder builder() {
		return new Builder();
	}

	/**
	 * Creates a mutation policy with a fixed number of repetitions.
	 *
	 * @param repetitions    number of times to apply the mutation policy
	 * @param mutationPolicy mutation policy to repeat
	 * @return a repeated mutation policy
	 */
	public static RepeatedMutation ofExactly(final int repetitions, final MutationPolicy mutationPolicy) {
		return ImmutableRepeatedMutation.of(repetitions, repetitions, mutationPolicy);
	}

	/**
	 * Creates a mutation policy with a number of repetitions selected uniformly between one and the specified maximum,
	 * inclusive.
	 *
	 * @param maxRepetitions maximum number of repetitions, inclusive
	 * @param mutationPolicy mutation policy to repeat
	 * @return a repeated mutation policy
	 */
	public static RepeatedMutation ofUpTo(final int maxRepetitions, final MutationPolicy mutationPolicy) {
		return ImmutableRepeatedMutation.of(1, maxRepetitions, mutationPolicy);
	}

	/**
	 * Creates a mutation policy with a variable number of repetitions.
	 *
	 * @param minRepetitions minimum number of repetitions, inclusive
	 * @param maxRepetitions maximum number of repetitions, inclusive
	 * @param mutationPolicy mutation policy to repeat
	 * @return a repeated mutation policy
	 */
	public static RepeatedMutation of(final int minRepetitions, final int maxRepetitions,
			final MutationPolicy mutationPolicy) {
		return ImmutableRepeatedMutation.of(minRepetitions, maxRepetitions, mutationPolicy);
	}
}