//=============================================================================
// Copyright 2006-2010 Daniel W. Dyer
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//=============================================================================
package org.uncommons.watchmaker.framework.operators;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import org.uncommons.maths.number.ConstantGenerator;
import org.uncommons.maths.number.NumberGenerator;
import org.uncommons.maths.random.Probability;
import org.uncommons.watchmaker.framework.CandidateFactory;
import org.uncommons.watchmaker.framework.EvolutionaryOperator;
/**
* An evolutionary operator that replaces individuals with randomly-generated
* new individuals, according to some specified probability. The new individuals
* are not derived from the selected individuals, they are completely random. This
* operator provides a way to prevent stagnation by occassionally introducing
* new genetic material into the population.
* @param <T> The type of evolvable entity that this operator applies to.
* @author Daniel Dyer
*/
public class Replacement<T> implements EvolutionaryOperator<T>
{
private final CandidateFactory<T> factory;
private final NumberGenerator<Probability> replacementProbability;
/**
* Creates a replacement operator that replaces individuals according to
* the specified probability. New individuals are obtained from the factory
* provided.
* @param factory A source of new individuals.
* @param replacementProbability The probability that any given individual will
* be replaced by a new individual. This should typically be quite low. If it is
* too high, it will undermine the evolutionary progress.
*/
public Replacement(CandidateFactory<T> factory,
Probability replacementProbability)
{
this(factory, new ConstantGenerator<Probability>(replacementProbability));
}
/**
* Creates a replacement operator that replaces individuals according to
* a variable probability. New individuals are obtained from the factory
* provided.
* @param factory A source of new individuals.
* @param replacementProbability A {@link NumberGenerator} that provides
* a probability of replacement. The probablity may be constant, or it may change
* over time. The probability should typically be quite low. If it is too high,
* it will undermine the evolutionary progress.
*/
public Replacement(CandidateFactory<T> factory,
NumberGenerator<Probability> replacementProbability)
{
this.factory = factory;
this.replacementProbability = replacementProbability;
}
/**
* Randomly replace zero or more of the selected candidates with new,
* independent individuals that are randomly created.
* @param selectedCandidates The selected candidates, some of these may be
* discarded and replaced with new individuals.
* @param rng A source of randomness.
* @return The remaining candidates after some (or none) have been replaced
* with new individuals.
*/
public List<T> apply(List<T> selectedCandidates, Random rng)
{
List<T> output = new ArrayList<T>(selectedCandidates.size());
for (T candidate : selectedCandidates)
{
output.add(replacementProbability.nextValue().nextEvent(rng)
? factory.generateRandomCandidate(rng)
: candidate);
}
return output;
}
}