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 * Tournament selection scheme. Each of the two selected chromosomes is selected
24dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * based on n-ary tournament -- this is done by drawing {@link #arity} random
25dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * chromosomes without replacement from the population, and then selecting the
26dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * fittest chromosome among them.
27dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond *
28dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @since 2.0
29dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $
30dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */
31dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondpublic class TournamentSelection implements SelectionPolicy {
32dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
33dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** number of chromosomes included in the tournament selections */
34dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private int arity;
35dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
36dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
37dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Creates a new TournamentSelection instance.
38dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
39dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param arity
40dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *            how many chromosomes will be drawn to the tournament
41dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
42dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public TournamentSelection(int arity) {
43dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        this.arity = arity;
44dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
45dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
46dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
47dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Select two chromosomes from the population. Each of the two selected
48dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * chromosomes is selected based on n-ary tournament -- this is done by
49dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * drawing {@link #arity} random chromosomes without replacement from the
50dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * population, and then selecting the fittest chromosome among them.
51dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
52dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param population
53dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *            the population from which the chromosomes are choosen.
54dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return the selected chromosomes.
55dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
56dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public ChromosomePair select(Population population) {
57dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return new ChromosomePair(
58dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                tournament((ListPopulation) population),
59dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                tournament((ListPopulation)population)
60dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                );
61dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
62dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
63dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
64dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Helper for {@link #select(Population)}. Draw {@link #arity} random
65dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * chromosomes without replacement from the population, and then select the
66dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * fittest chromosome among them.
67dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
68dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param population
69dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *            the population from which the chromosomes are choosen.
70dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return the selected chromosome.
71dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
72dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private Chromosome tournament(ListPopulation population) {
73dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        if (population.getPopulationSize() < this.arity)
74dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            throw new IllegalArgumentException("Tournament arity cannot be bigger than population size.");
75dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        // auxiliary population
76dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        ListPopulation tournamentPopulation = new ListPopulation(this.arity) {
77dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            public Population nextGeneration() {
78dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                // not useful here
79dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                return null;
80dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            }
81dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        };
82dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
83dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        // create a copy of the chromosome list
84dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        List<Chromosome> chromosomes = new ArrayList<Chromosome> (population.getChromosomes());
85dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        for (int i=0; i<this.arity; i++) {
86dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            // select a random individual and add it to the tournament
87dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            int rind = GeneticAlgorithm.getRandomGenerator().nextInt(chromosomes.size());
88dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            tournamentPopulation.addChromosome(chromosomes.get(rind));
89dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            // do not select it again
90dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            chromosomes.remove(rind);
91dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
92dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        // the winner takes it all
93dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return tournamentPopulation.getFittestChromosome();
94dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
95dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
96dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
97dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Gets the arity (number of chromosomes drawn to the tournament).
98dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
99dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return arity of the tournament
100dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
101dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public int getArity() {
102dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return arity;
103dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
104dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
105dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
106dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Sets the arity (number of chromosomes drawn to the tournament).
107dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
108dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param arity arity of the tournament
109dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
110dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public void setArity(int arity) {
111dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        this.arity = arity;
112dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
113dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
114dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond}
115