termination.java
001 /*
002  * Java Genetic Algorithm Library (jenetics-1.6.0).
003  * Copyright (c) 2007-2014 Franz Wilhelmstötter
004  *
005  * Licensed under the Apache License, Version 2.0 (the "License");
006  * you may not use this file except in compliance with the License.
007  * You may obtain a copy of the License at
008  *
009  *      http://www.apache.org/licenses/LICENSE-2.0
010  *
011  * Unless required by applicable law or agreed to in writing, software
012  * distributed under the License is distributed on an "AS IS" BASIS,
013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014  * See the License for the specific language governing permissions and
015  * limitations under the License.
016  *
017  * Author:
018  *    Franz Wilhelmstötter (franz.wilhelmstoetter@gmx.at)
019  */
020 package org.jenetics;
021 
022 import org.jenetics.util.Function;
023 import org.jenetics.util.StaticObject;
024 
025 /**
026  * Some default GA termination strategies.
027  *
028  @author <a href="mailto:franz.wilhelmstoetter@gmx.at">Franz Wilhelmstötter</a>
029  @since 1.0
030  @version 1.0 &mdash; <em>$Date: 2014-02-14 $</em>
031  */
032 public final class termination extends StaticObject {
033     private termination() {}
034 
035     static class SteadyFitness<C extends Comparable<? super C>>
036         implements Function<Statistics<?, C>, Boolean>
037     {
038         private final int _generations;
039 
040         private C _fitness;
041         private int _stableGenerations = 0;
042 
043         public SteadyFitness(final int generations) {
044             _generations = generations;
045         }
046 
047         @Override
048         public Boolean apply(final Statistics<?, C> statistics) {
049             boolean proceed = true;
050 
051             if (_fitness == null) {
052                 _fitness = statistics.getBestFitness();
053                 _stableGenerations = 1;
054             else {
055                 final Optimize opt = statistics.getOptimize();
056                 if (opt.compare(_fitness, statistics.getBestFitness()) >= 0) {
057                     proceed = ++_stableGenerations <= _generations;
058                 else {
059                     _fitness = statistics.getBestFitness();
060                     _stableGenerations = 1;
061                 }
062             }
063 
064             return proceed ? Boolean.TRUE : Boolean.FALSE;
065         }
066     }
067 
068     /**
069      * Create a <i>terminator</i> which returns {@code false} if the fitness
070      * hasn't improved for a given number of generations.
071      *
072      @param <C> the fitness type.
073      @param generation the number of generations the fitness don't have been
074      *         improved.
075      @return the GA terminator.
076      */
077     public static <C extends Comparable<? super C>>
078     Function<Statistics<?, C>, Boolean> SteadyFitness(final int generation) {
079         return new SteadyFitness<>(generation);
080     }
081 
082     static class Generation implements Function<Statistics<?, ?>, Boolean> {
083         private final int _generation;
084 
085         public Generation(final int generation) {
086             _generation = generation;
087         }
088 
089         @Override
090         public Boolean apply(final Statistics<?, ?> statistics) {
091             return statistics.getGeneration() < _generation ?
092                     Boolean.TRUE :
093                     Boolean.FALSE;
094         }
095     }
096 
097     /**
098      * Return a <i>termination predicate</i> which returns {@code false} if the
099      * current GA generation is {@code >=} as the given {@code generation}.
100      *
101      * [code]
102      * final GeneticAlgorithm<DoubleGene, Double> ga = ...
103      * ga.evolve(termination.Generation(100));
104      * [/code]
105      *
106      @param generation the maximal GA generation.
107      @return the termination predicate.
108      */
109     public static Function<Statistics<?, ?>, Boolean>
110     Generation(final int generation) {
111         return new Generation(generation);
112     }
113 
114 }