All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jenetics.LineCrossover Maven / Gradle / Ivy

/*
 * Java Genetic Algorithm Library (jenetics-3.9.0).
 * Copyright (c) 2007-2017 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.Math.min;
import static java.lang.String.format;
import static org.jenetics.internal.math.random.nextDouble;

import java.util.Random;

import org.jenetics.internal.util.Hash;
import org.jenetics.internal.util.require;

import org.jenetics.util.MSeq;
import org.jenetics.util.RandomRegistry;

/**
 * This alterer takes two chromosome (treating it as vectors) and creates a
 * linear combination of this vectors as result. The  line-recombination depends
 * on a variable p which determines how far out along the line (defined
 * by the two multidimensional points/vectors) the children are allowed to be.
 * If p = 0 then the children will be located along the line within the
 * hypercube between the two points. If p > 0 then the children may
 * be located anywhere on the line, even somewhat outside of the hypercube.
 * 

* Points outside of the allowed numeric range are rejected and the original * value are used instead. The strategy on how out-of-range points are handled, * is the difference to the very similar {@link IntermediateCrossover}. * * @see * Essentials of Metaheuristic, page 42 * @see IntermediateCrossover * * @author Franz Wilhelmstötter * @version 3.8 * @since 3.8 */ public class LineCrossover< G extends NumericGene, C extends Comparable > extends Crossover { private final double _p; /** * Creates a new linear-crossover with the given recombination * probability and the line-scaling factor p. * * @param probability the recombination probability. * @param p defines the possible location of the recombined chromosomes. If * p = 0 then the children will be located along the line * within the hypercube between the two points. If p > 0 * then the children may be located anywhere on the line, even * somewhat outside of the hypercube. * @throws IllegalArgumentException if the {@code probability} is not in the * valid range of {@code [0, 1]} or if {@code p} is smaller then zero */ public LineCrossover(final double probability, final double p) { super(probability); _p = require.nonNegative(p, "p"); } /** * Creates a new linear-crossover with the given recombination * probability. The parameter p is set to zero, which restricts the * recombined chromosomes within the hypercube of the selected chromosomes * (vectors). * * @param probability the recombination probability. * @throws IllegalArgumentException if the {@code probability} is not in the * valid range of {@code [0, 1]} */ public LineCrossover(final double probability) { this(probability, 0); } /** * Creates a new linear-crossover with default recombination * probability ({@link #DEFAULT_ALTER_PROBABILITY}) and a p value * of zero, which restricts the recombined chromosomes within the hypercube * of the selected chromosomes (vectors). */ public LineCrossover() { this(DEFAULT_ALTER_PROBABILITY, 0); } @Override protected int crossover(final MSeq v, final MSeq w) { final Random random = RandomRegistry.getRandom(); final double min = v.get(0).getMin().doubleValue(); final double max = v.get(0).getMax().doubleValue(); final double a = nextDouble(random, -_p, 1 + _p); final double b = nextDouble(random, -_p, 1 + _p); boolean changed = false; for (int i = 0, n = min(v.length(), w.length()); i < n; ++i) { final double vi = v.get(i).doubleValue(); final double wi = w.get(i).doubleValue(); final double t = a*vi + (1 - a)*wi; final double s = b*wi + (1 - b)*vi; if (t >= min && s >= min && t < max && s < max) { v.set(i, v.get(i).newInstance(t)); w.set(i, w.get(i).newInstance(s)); changed = true; } } return changed ? 2 : 0; } @Override public int hashCode() { return Hash.of(getClass()).and(super.hashCode()).value(); } @Override public boolean equals(final Object obj) { return obj instanceof LineCrossover && super.equals(obj); } @Override public String toString() { return format("%s[p=%f]", getClass().getSimpleName(), _probability); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy