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  public class FitnessCachingTest {
28  
29      // parameters for the GA
30      private static final int DIMENSION = 50;
31      private static final double CROSSOVER_RATE = 1;
32      private static final double MUTATION_RATE = 0.1;
33      private static final int TOURNAMENT_ARITY = 5;
34  
35      private static final int POPULATION_SIZE = 10;
36      private static final int NUM_GENERATIONS = 50;
37      private static final double ELITISM_RATE = 0.2;
38  
39      // how many times was the fitness computed
40      private static int fitnessCalls = 0;
41  
42  
43      @Test
44      public void testFitnessCaching() {
45          // initialize a new genetic algorithm
46          GeneticAlgorithm ga = new GeneticAlgorithm(
47                  new OnePointCrossover<>(),
48                  CROSSOVER_RATE, // all selected chromosomes will be recombined (=crosssover)
49                  new BinaryMutation(),
50                  MUTATION_RATE, // no mutation
51                  new TournamentSelection(TOURNAMENT_ARITY)
52          );
53  
54          // initial population
55          Population initial = randomPopulation();
56          // stopping conditions
57          StoppingCondition stopCond = new FixedGenerationCount(NUM_GENERATIONS);
58  
59          // run the algorithm
60          ga.evolve(initial, stopCond);
61  
62          int neededCalls =
63              POPULATION_SIZE /*initial population*/ +
64              (NUM_GENERATIONS - 1) /*for each population*/ * (int)(POPULATION_SIZE * (1.0 - ELITISM_RATE)) /*some chromosomes are copied*/
65              ;
66          Assert.assertTrue(fitnessCalls <= neededCalls); // some chromosomes after crossover may be the same os old ones
67      }
68  
69  
70      /**
71       * Initializes a random population.
72       */
73      private static ElitisticListPopulation randomPopulation() {
74          List<Chromosome> popList = new LinkedList<>();
75  
76          for (int i=0; i<POPULATION_SIZE; i++) {
77              BinaryChromosome randChrom = new DummyCountingBinaryChromosome(BinaryChromosome.randomBinaryRepresentation(DIMENSION));
78              popList.add(randChrom);
79          }
80          return new ElitisticListPopulation(popList, popList.size(), ELITISM_RATE);
81      }
82  
83      private static final class DummyCountingBinaryChromosome extends DummyBinaryChromosome {
84  
85          DummyCountingBinaryChromosome(List<Integer> representation) {
86              super(representation);
87          }
88  
89          @Override
90          public double fitness() {
91              fitnessCalls++;
92              return 0;
93          }
94      }
95  }