1dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond/*
2dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Licensed to the Apache Software Foundation (ASF) under one or more
3dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * contributor license agreements.  See the NOTICE file distributed with
4dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * this work for additional information regarding copyright ownership.
5dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * The ASF licenses this file to You under the Apache License, Version 2.0
6dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * (the "License"); you may not use this file except in compliance with
7dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * the License.  You may obtain a copy of the License at
8dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond *
9dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond *      http://www.apache.org/licenses/LICENSE-2.0
10dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond *
11dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Unless required by applicable law or agreed to in writing, software
12dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * distributed under the License is distributed on an "AS IS" BASIS,
13dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * See the License for the specific language governing permissions and
15dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * limitations under the License.
16dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */
17dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondpackage org.apache.commons.math.genetics;
18dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
19dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport java.util.ArrayList;
20dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport java.util.List;
21dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
22dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
23dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond/**
24dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * One point crossover policy. A random crossover point is selected and the
25dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * first part from each parent is copied to the corresponding child, and the
26dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * second parts are copied crosswise.
27dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond *
28dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Example:
29dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <pre>
30dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * -C- denotes a crossover point
31dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond *                   -C-                                -C-
32dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * p1 = (1 0 1 0 0 1  | 0 1 1)    X    p2 = (0 1 1 0 1 0  | 1 1 1)
33dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond *         \------------/ \-----/              \------------/ \-----/
34dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond *            ||         (*)                       ||        (**)
35dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond *            VV         (**)                      VV        (*)
36dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond *      /------------\ /-----\              /------------\ /-----\
37dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * c1 = (1 0 1 0 0 1  | 1 1 1)    X    p2 = (0 1 1 0 1 0  | 0 1 1)
38dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * </pre>
39dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond *
40dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * This policy works only on {@link AbstractListChromosome}, and therefore it
41dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * is parametrized by T. Moreover, the chromosomes must have same lengths.
42dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond *
43dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param <T> generic type of the {@link AbstractListChromosome}s for crossover
44dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @since 2.0
45dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @version $Revision: 903046 $ $Date: 2010-01-26 03:07:26 +0100 (mar. 26 janv. 2010) $
46dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond *
47dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */
48dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondpublic class OnePointCrossover<T> implements CrossoverPolicy {
49dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
50dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
51dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Performs one point crossover. A random crossover point is selected and the
52dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * first part from each parent is copied to the corresponding child, and the
53dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * second parts are copied crosswise.
54dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
55dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Example:
56dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * -C- denotes a crossover point
57dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *                   -C-                                -C-
58dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * p1 = (1 0 1 0 0 1  | 0 1 1)    X    p2 = (0 1 1 0 1 0  | 1 1 1)
59dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *         \------------/ \-----/              \------------/ \-----/
60dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *            ||         (*)                       ||        (**)
61dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *            VV         (**)                      VV        (*)
62dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *      /------------\ /-----\              /------------\ /-----\
63dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * c1 = (1 0 1 0 0 1  | 1 1 1)    X    p2 = (0 1 1 0 1 0  | 0 1 1)
64dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
65dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param first first parent (p1)
66dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param second second parent (p2)
67dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return pair of two children (c1,c2)
68dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
69dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    @SuppressWarnings("unchecked") // OK because of instanceof checks
70dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public ChromosomePair crossover(Chromosome first, Chromosome second) {
71dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        if (! (first instanceof AbstractListChromosome<?> && second instanceof AbstractListChromosome<?>)) {
72dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            throw new IllegalArgumentException("One point crossover works on FixedLengthChromosomes only.");
73dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
74dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return crossover((AbstractListChromosome<T>) first, (AbstractListChromosome<T>) second);
75dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
76dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
77dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
78dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
79dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Helper for {@link #crossover(Chromosome, Chromosome)}. Performs the actual crossover.
80dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
81dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param first the first chromosome.
82dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param second the second chromosome.
83dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return the pair of new chromosomes that resulted from the crossover.
84dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
85dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private ChromosomePair crossover(AbstractListChromosome<T> first, AbstractListChromosome<T> second) {
86dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        int length = first.getLength();
87dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        if (length != second.getLength())
88dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            throw new IllegalArgumentException("Both chromosomes must have same lengths.");
89dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
90dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        // array representations of the parents
91dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        List<T> parent1Rep = first.getRepresentation();
92dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        List<T> parent2Rep = second.getRepresentation();
93dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        // and of the children
94dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        ArrayList<T> child1Rep = new ArrayList<T> (first.getLength());
95dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        ArrayList<T> child2Rep = new ArrayList<T> (second.getLength());
96dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
97dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        // select a crossover point at random (0 and length makes no sense)
98dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        int crossoverIndex = 1 + (GeneticAlgorithm.getRandomGenerator().nextInt(length-2));
99dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
100dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        // copy the first part
101dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        for (int i = 0; i < crossoverIndex; i++) {
102dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            child1Rep.add(parent1Rep.get(i));
103dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            child2Rep.add(parent2Rep.get(i));
104dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
105dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        // and switch the second part
106dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        for (int i = crossoverIndex; i < length; i++) {
107dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            child1Rep.add(parent2Rep.get(i));
108dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            child2Rep.add(parent1Rep.get(i));
109dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
110dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
111dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return new ChromosomePair(
112dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                first.newFixedLengthChromosome(child1Rep),
113dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                second.newFixedLengthChromosome(child2Rep)
114dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                );
115dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
116dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
117dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond}
118