View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.math4.legacy.genetics;
18  
19  
20  import java.util.LinkedList;
21  import java.util.List;
22  
23  import org.junit.Assert;
24  import org.junit.Test;
25  
26  /**
27   * This is also an example of usage.
28   */
29  public class GeneticAlgorithmTestBinary {
30  
31      // parameters for the GA
32      private static final int DIMENSION = 50;
33      private static final int POPULATION_SIZE = 50;
34      private static final int NUM_GENERATIONS = 50;
35      private static final double ELITISM_RATE = 0.2;
36      private static final double CROSSOVER_RATE = 1;
37      private static final double MUTATION_RATE = 0.1;
38      private static final int TOURNAMENT_ARITY = 2;
39  
40      @Test
41      public void test() {
42          // to test a stochastic algorithm is hard, so this will rather be an usage example
43  
44          // initialize a new genetic algorithm
45          GeneticAlgorithm ga = new GeneticAlgorithm(
46                  new OnePointCrossover<>(),
47                  CROSSOVER_RATE, // all selected chromosomes will be recombined (=crossover)
48                  new BinaryMutation(),
49                  MUTATION_RATE,
50                  new TournamentSelection(TOURNAMENT_ARITY)
51          );
52  
53          Assert.assertEquals(0, ga.getGenerationsEvolved());
54  
55          // initial population
56          Population initial = randomPopulation();
57          // stopping conditions
58          StoppingCondition stopCond = new FixedGenerationCount(NUM_GENERATIONS);
59  
60          // best initial chromosome
61          Chromosome bestInitial = initial.getFittestChromosome();
62  
63          // run the algorithm
64          Population finalPopulation = ga.evolve(initial, stopCond);
65  
66          // best chromosome from the final population
67          Chromosome bestFinal = finalPopulation.getFittestChromosome();
68  
69          // the only thing we can test is whether the final solution is not worse than the initial one
70          // however, for some implementations of GA, this need not be true :)
71  
72          Assert.assertTrue(bestFinal.compareTo(bestInitial) > 0);
73          Assert.assertEquals(NUM_GENERATIONS, ga.getGenerationsEvolved());
74      }
75  
76  
77  
78  
79      /**
80       * Initializes a random population.
81       */
82      private static ElitisticListPopulation randomPopulation() {
83          List<Chromosome> popList = new LinkedList<>();
84  
85          for (int i=0; i<POPULATION_SIZE; i++) {
86              BinaryChromosome randChrom = new FindOnes(BinaryChromosome.randomBinaryRepresentation(DIMENSION));
87              popList.add(randChrom);
88          }
89          return new ElitisticListPopulation(popList, popList.size(), ELITISM_RATE);
90      }
91  
92      /**
93       * Chromosomes represented by a binary chromosome.
94       *
95       * The goal is to set all bits (genes) to 1.
96       */
97      private static final class FindOnes extends BinaryChromosome {
98  
99          FindOnes(List<Integer> representation) {
100             super(representation);
101         }
102 
103         /**
104          * Returns number of elements != 0
105          */
106         @Override
107         public double fitness() {
108             int num = 0;
109             for (int val : this.getRepresentation()) {
110                 if (val != 0) {
111                     num++;
112                 }
113             }
114             // number of elements >= 0
115             return num;
116         }
117 
118         @Override
119         public AbstractListChromosome<Integer> newFixedLengthChromosome(List<Integer> chromosomeRepresentation) {
120             return new FindOnes(chromosomeRepresentation);
121         }
122     }
123 }