/*
 * Java Genetic Algorithm Library (@__identifier__@).
 * Copyright (c) @__year__@ 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 (franz.wilhelmstoetter@gmx.at)
 */
package org.jenetics;

import java.util.Random;

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

/**
 * <p>
 * Performs a <a href="http://en.wikipedia.org/wiki/Crossover_%28genetic_algorithm%29">
 * Crossover</a> of two {@link Chromosome}.
 * </p>
 * <p>
 * The order ({@link #getOrder()}) of this Recombination implementation is two.
 * </p>
 *
 * @param <G> the gene type.
 *
 * @author <a href="mailto:franz.wilhelmstoetter@gmx.at">Franz Wilhelmstötter</a>
 * @since 1.0
 * @version 3.0
 */
public abstract class Crossover<
	G extends Gene<?, G>,
	C extends Comparable<? super C>
>
	extends Recombinator<G, C>
{

	/**
	 * Constructs an alterer with a given recombination probability.
	 *
	 * @param probability the recombination probability
	 * @throws IllegalArgumentException if the {@code probability} is not in the
	 *          valid range of {@code [0, 1]}
	 */
	protected Crossover(final double probability) {
		super(probability, 2);
	}

	@Override
	protected final int recombine(
		final Population<G, C> population,
		final int[] individuals,
		final long generation
	) {
		final Random random = RandomRegistry.getRandom();

		final Phenotype<G, C> pt1 = population.get(individuals[0]);
		final Phenotype<G, C> pt2 = population.get(individuals[1]);
		final Genotype<G> gt1 = pt1.getGenotype();
		final Genotype<G> gt2 = pt2.getGenotype();

		//Choosing the Chromosome for crossover.
		final int chIndex = random.nextInt(gt1.length());

		final MSeq<Chromosome<G>> c1 = gt1.toSeq().copy();
		final MSeq<Chromosome<G>> c2 = gt2.toSeq().copy();
		final MSeq<G> genes1 = c1.get(chIndex).toSeq().copy();
		final MSeq<G> genes2 = c2.get(chIndex).toSeq().copy();

		crossover(genes1, genes2);

		c1.set(chIndex, c1.get(chIndex).newInstance(genes1.toISeq()));
		c2.set(chIndex, c2.get(chIndex).newInstance(genes2.toISeq()));

		//Creating two new Phenotypes and exchanging it with the old.
		population.set(
			individuals[0],
			pt1.newInstance(gt1.newInstance(c1.toISeq()), generation)
		);
		population.set(
			individuals[1],
			pt2.newInstance(gt1.newInstance(c2.toISeq()), generation)
		);

		return getOrder();
	}

	/**
	 * Template method which performs the crossover. The arguments given are
	 * mutable non null arrays of the same length.
	 *
	 * @param that the genes of the first chromosome
	 * @param other the genes of the other chromosome
	 * @return the number of altered genes
	 */
	protected abstract int crossover(final MSeq<G> that, final MSeq<G> other);

}

@@ -757,16 +757,51 @@
 etics;%0A%0A
+import static java.lang.Math.min;%0A%0A
 import j
@@ -817,16 +817,16 @@
 Random;%0A
-
 %0Aimport 
@@ -1033,16 +1033,237 @@
 mosome%7D.
+ This crossover implementation can%0A * handle genotypes with different length (different number of chromosomes). It%0A * is guaranteed that chromosomes with the the same (genotype) index are chosen%0A * for %3Cem%3Ecrossover%3C/em%3E.
 %0A * %3C/p%3E
@@ -1505,11 +1505,21 @@
 ion 
-3.0
+!__version__!
 %0A */
@@ -2109,16 +2109,74 @@
 on%0A%09) %7B%0A
+%09%09assert individuals.length == 2 : %22Required order of 2%22;%0A
 %09%09final 
@@ -2463,16 +2463,22 @@
 omosome 
+index 
 for cros
@@ -2521,16 +2521,20 @@
 nextInt(
+min(
 gt1.leng
@@ -2537,16 +2537,31 @@
 length()
+, gt2.length())
 );%0A%0A%09%09fi

Make 'Crossover' class ready for genotypes with different length.