org.jenetics.Recombinator Maven / Gradle / Ivy
/*
* Java Genetic Algorithm Library (jenetics-3.4.0).
* Copyright (c) 2007-2016 Franz Wilhelmstötter
*
* 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.
*
* Author:
* Franz Wilhelmstötter ([email protected])
*/
package org.jenetics;
import static java.lang.String.format;
import static org.jenetics.internal.math.base.subset;
import static org.jenetics.internal.math.random.indexes;
import java.util.Random;
import java.util.function.IntFunction;
import org.jenetics.util.RandomRegistry;
/**
*
* An enhanced genetic algorithm (EGA) combine elements of existing solutions in
* order to create a new solution, with some of the properties of each parent.
* Recombination creates a new chromosome by combining parts of two (or more)
* parent chromosomes. This combination of chromosomes can be made by selecting
* one or more crossover points, splitting these chromosomes on the selected
* points, and merge those portions of different chromosomes to form new ones.
*
*
* The recombination probability P(r) determines the probability that a
* given individual (genotype, not gene) of a population is selected for
* recombination. The (mean) number of changed individuals depend on the
* concrete implementation and can be vary from
* P(r)·NG to
* P(r)·NG·OR, where
* OR is the order of the recombination, which is the number
* of individuals involved int the {@link #recombine} method.
*
*
* @author Franz Wilhelmstötter
* @since 1.0
* @version 3.0
*/
public abstract class Recombinator<
G extends Gene, G>,
C extends Comparable super C>
>
extends AbstractAlterer
{
private final int _order;
/**
* Constructs an alterer with a given recombination probability.
*
* @param probability The recombination probability.
* @param order the number of individuals involved in the
* {@link #recombine(Population, int[], long)} step
* @throws IllegalArgumentException if the {@code probability} is not in the
* valid range of {@code [0, 1]} or the given {@code order} is
* smaller than two.
*/
protected Recombinator(final double probability, final int order) {
super(probability);
if (order < 2) {
throw new IllegalArgumentException(format(
"Order must be greater than one, but was %d.", order
));
}
_order = order;
}
/**
* Return the number of individuals involved in the
* {@link #recombine(Population, int[], long)} step.
*
* @return the number of individuals involved in the recombination step.
*/
public int getOrder() {
return _order;
}
@Override
public final int alter(
final Population population,
final long generation
) {
int count = 0;
if (population.size() >= 2) {
final Random random = RandomRegistry.getRandom();
final int order = Math.min(_order, population.size());
final IntFunction individuals = i -> {
final int[] ind = subset(population.size(), order, random);
ind[0] = i;
return ind;
};
count = indexes(random, population.size(), _probability)
.mapToObj(individuals)
.mapToInt(i -> recombine(population, i, generation))
.sum();
}
return count;
}
/**
* Recombination template method.
*
* @param population the population to recombine
* @param individuals the array with the indexes of the individuals which
* are involved in the recombination step. The length of the
* array is {@link #getOrder()}. The first individual is the
* primary individual.
* @param generation the current generation.
* @return the number of genes that has been altered.
*/
protected abstract int recombine(
final Population population,
final int[] individuals,
final long generation
);
}