jenes.tutorials.problem2.PatternProblem

001 /*
002  * JENES
003  * A time and memory efficient Java library for genetic algorithms and more 
004  * Copyright (C) 2011 Intelligentia srl
005  *
006  * This program is free software: you can redistribute it and/or modify
007  * it under the terms of the GNU General Public License as published by
008  * the Free Software Foundation, either version 3 of the License, or
009  * (at your option) any later version.
010  *
011  *  This program is distributed in the hope that it will be useful,
012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
014  *  GNU General Public License for more details.
015  *
016  *  You should have received a copy of the GNU General Public License
017  *  along with this program.  If not, see <http://www.gnu.org/licenses/>. 
018  */
019 package jenes.tutorials.problem2;
020 
021 import jenes.GenerationEventListener;
022 import jenes.GeneticAlgorithm;
023 import jenes.utils.Random;
024 import jenes.chromosome.IntegerChromosome;
025 import jenes.population.Individual;
026 import jenes.population.Population;
027 import jenes.population.Population.Statistics;
028 import jenes.population.Population.Statistics.Group;
029 import jenes.stage.AbstractStage;
030 import jenes.stage.Parallel;
031 import jenes.stage.operator.common.OnePointCrossover;
032 import jenes.stage.operator.common.SimpleMutator;
033 import jenes.stage.operator.common.TournamentSelector;
034 import jenes.stage.operator.common.TwoPointsCrossover;
035 import jenes.tutorials.utils.Utils;
036 
037 
038 /**
039  * Tutorial showing how to extend <code>GeneticAlgorithm</code> and how to use
040  * the flexible and configurable breeding structure in Jenes.
041  * The problem consists in searching a pattern of integers with a given precision.
042  * Solutions flow through two different crossovers in parallel. Some are processed by
043  * a single point crossover, the other by a double point crossover.
044  * After solutions are mutated.
045  *
046  * This is the main class that specifies the problem.
047  *
048  @author Luigi Troiano
049  *
050  @version 2.0
051  *
052  @since 1.0
053  */
054 public class PatternProblem implements GenerationEventListener<IntegerChromosome> {
055     
056     private static int POPULATION_SIZE = 100;
057     private static int CHROMOSOME_LENGTH = 10;
058     private static int GENERATION_LIMIT = 1000;
059     private static int MAX_INT = 49;
060     
061     private PatternGA algorithm = null;
062     
063     public PatternProblem() {
064         
065         IntegerChromosome chrom = new IntegerChromosome(CHROMOSOME_LENGTH,0,MAX_INT);
066         Individual<IntegerChromosome> ind = new Individual<IntegerChromosome>(chrom);
067         Population<IntegerChromosome> pop = new Population<IntegerChromosome>(ind, POPULATION_SIZE);
068         
069         algorithm = new PatternGA(pop, GENERATION_LIMIT);
070         algorithm.setElitism(5);
071         
072         AbstractStage<IntegerChromosome> selection = new TournamentSelector<IntegerChromosome>(2);
073         
074         Parallel<IntegerChromosome> parallel = new Parallel<IntegerChromosome>(new SimpleDispenser<IntegerChromosome>(2));
075         
076         AbstractStage<IntegerChromosome> crossover1p = new OnePointCrossover<IntegerChromosome>(0.8);
077         parallel.add(crossover1p);
078         
079         AbstractStage<IntegerChromosome> crossover2p = new TwoPointsCrossover<IntegerChromosome>(0.5);
080         parallel.add(crossover2p);
081         
082         AbstractStage<IntegerChromosome> mutation = new SimpleMutator<IntegerChromosome>(0.02);
083         
084         algorithm.addStage(selection);
085         algorithm.addStage(parallel);
086         algorithm.addStage(mutation);
087         algorithm.addGenerationEventListener(this);
088     }
089     
090     public void run(int[] target, int precision) {
091         ((PatternGA.PatternFitnessalgorithm.getFitness()).setTarget(target);
092         ((PatternGA.PatternFitnessalgorithm.getFitness()).setPrecision(precision);
093         algorithm.evolve();
094         
095         Population.Statistics stats = algorithm.getCurrentPopulation().getStatistics();
096         GeneticAlgorithm.Statistics algostats = algorithm.getStatistics();
097         
098         System.out.println();
099         System.out.print("Target:[");
100         forint i = 0; i < target.length; ++i ) {
101             System.out.print(target[i]i < target.length - " " ""));
102         }
103         System.out.println("]");
104         System.out.println();
105         
106         System.out.println("Solution: ");
107         System.out.println(stats.getGroup(Population.LEGALS).get(0));
108         System.out.format("found in %d ms and %d generations.\n", algostats.getExecutionTime(), algostats.getGenerations() );
109         System.out.println();
110     }
111     
112     
113     public void onGeneration(GeneticAlgorithm ga, long time) {
114         Statistics stat = ga.getCurrentPopulation().getStatistics();
115         Group legals = stat.getGroup(Population.LEGALS);
116         System.out.println("Current generation: " + ga.getGeneration());
117         System.out.println("\tBest score: " + legals.getMin()[0]);
118         System.out.println("\tAvg score : " + legals.getMean()[0]);
119     }
120     
121     private static void randomize(int[] sample) {
122         for(int i=0;i<sample.length;i++)
123             sample[i= Random.getInstance().nextInt(0, MAX_INT+1);
124     }
125     
126     public static void main(String[] args) {
127         
128         Utils.printHeader();
129         System.out.println();
130         
131         System.out.println("TUTORIAL 2:");
132         System.out.println("This algorithm aims to autonomously find a vector of integers that best matches with a target vector.");
133         System.out.println();
134         
135         Random.getInstance().setStandardSeed();
136         
137         PatternProblem problem = new PatternProblem();
138         int[] target = new int[CHROMOSOME_LENGTH];
139         
140         randomize(target);
141         problem.run(target, 2);
142         
143         randomize(target);
144         problem.run(target, 0);
145         
146     }
147     
148 }