View Javadoc
1   /**
2    * @(#)Population.java
3    * Copyright (C) 2008-2011 delhezi.com
4    *
5    * This class is released under the:
6    * GNU Lesser General Public License (LGPL) version 3 or later.
7    * http://www.gnu.org/copyleft/lesser.html
8    */
9   package com.delhezi.ga;
10  
11  import com.delhezi.ga.crossover.ICrossover;
12  import com.delhezi.ga.crossover.factory.CrossoverFactory;
13  import com.delhezi.ga.crossover.factory.CrossoverOperatorType;
14  import com.delhezi.ga.exception.GeneticAlgorithmException;
15  import com.delhezi.ga.mutation.IMutation;
16  import com.delhezi.ga.mutation.factory.MutationFactory;
17  import com.delhezi.ga.mutation.factory.MutationOperatorType;
18  import java.util.LinkedList;
19  import java.util.logging.Logger;
20  
21  /**
22   * <code>Population</code>: Abstrakcyjna klasa populacji.
23   * @version 1.0 2010-05-14
24   * @author <a href="mailto:wojciech.wolszczak@delhezi.com">
25   * Wojciech Wolszczak</a>
26   */
27  public abstract class Population {
28  
29      /** Logger object. */
30      //private static final Logger LOGGER =
31      //    Logger.getLogger(Population.class.getName());
32  
33      /** Delhezi Error Code. */
34      //private static final String DERC = "1-6-";
35  
36      /**
37       * Konstruktor.
38       * @param chromosomes Lista chromosomów.
39       * @param crossoverOperator Operator krzyżowania.
40       * @param crossoverProbability Prawdopdobiestwo krzyżowania.
41       * @param mutationOperator Operator mutacji.
42       * @param mutationProbability Prawdopodobiestwo mutacji.
43       * @param chromosomeProperties Referencja do obiektu przechowującego
44       * parametry wspólne dla wszystkich chromosomów w ramach jednej
45       * instancji populacji.
46       * @throws GeneticAlgorithmException xxx
47       * @since 1.0
48       */
49      protected Population(final LinkedList<Chromosome> chromosomes,
50                           final ICrossover crossoverOperator,
51                           final double crossoverProbability,
52                           final IMutation mutationOperator,
53                           final double mutationProbability,
54                           final ChromosomeProperties chromosomeProperties)
55      throws GeneticAlgorithmException {
56          //W konstruktorze i metodzie clone inicjuj bezposrednio
57          //wartości zmiennych lub wywołuj tylko metody final.
58          this.chromosomes = chromosomes;
59          this.crossover = crossoverOperator;
60          this.crossoverProbability = crossoverProbability;
61          this.mutation = mutationOperator;
62          this.mutationProbability = mutationProbability;
63          this.chromosomeProperties = chromosomeProperties;
64          this.topChromosome = this.findTopChromosome();
65          this.topChromosomeGenerationFound = this.generation;
66          }
67  
68      /**
69       * Tworzenie populacji: t+1.
70       * @throws GeneticAlgorithmException xxx
71       * @since 1.0
72       */
73      abstract void generation() throws GeneticAlgorithmException;
74  
75      /**
76       * Ustawia referencję do obiektu implementującego operator krzyżowania.
77       * @param crossover Referencja do obiektu implementującego
78       * operator krzyżowania.
79       * @since 1.0
80       */
81      public final void setCrossover(final ICrossover crossover) {
82          this.crossover = crossover;
83      }
84  
85      /**
86       * Ustawia referencję do obiektu implementującego operator krzyżowania.
87       * @param crossoverOperator Typ operatora krzyżowania.
88       * @throws GeneticAlgorithmException xxx
89       * @since 1.0
90       */
91      public final void setCrossover(
92                                final CrossoverOperatorType crossoverOperator)
93      throws GeneticAlgorithmException {
94          this.crossover =
95                  CrossoverFactory.getCrossoverOperator(crossoverOperator);
96      }
97  
98      /**
99       * Zwraca referencję do obiektu implementującego operator krzyżowania.
100      * @return Referencja do obiektu implementującego operator krzyżowania.
101      * @since 1.0
102      */
103     public final ICrossover getCrossover() {
104         return this.crossover;
105     }
106 
107     /**
108      * Ustawia referencję do obiektu implementującego operator mutacji.
109      * @param mutation Referencja do obiektu implementującego operator mutacji.
110      * @since 1.0
111      */
112     public final void setMutation(final IMutation mutation) {
113         this.mutation = mutation;
114     }
115 
116     /**
117      * Ustawia referencję do obiektu implementującego operator mutacji.
118      * @param mutationOperator Typ operatora mutacji.
119      * @throws GeneticAlgorithmException xxx
120      * @since 1.0
121      */
122     public final void setMutation(final MutationOperatorType mutationOperator)
123     throws GeneticAlgorithmException {
124         this.mutation = MutationFactory.getMutationOperator(mutationOperator);
125     }
126 
127     /**
128      * Zwraca referencję do objektu implementującego operator mutacji.
129      * @return Referencja do obiektu implementującego operator mutacji.
130      * @since 1.0
131      */
132     public final IMutation getMutation() {
133         return this.mutation;
134     }
135 
136     /**
137      * Ustawia referencję do do obiektu przechowującego
138      * parametry wspólne dla wszystkich chromosomów w ramach jednej
139      * instancji populacji.
140      * @param chromosomeProperties Referencja do obiektu.
141      * @since 1.0
142      */
143     public final void setChromosomeProperties(
144                           final ChromosomeProperties chromosomeProperties) {
145         this.chromosomeProperties = chromosomeProperties;
146         }
147 
148     /**
149      * Zwraca referencję do do obiektu przechowującego
150      * parametry wspólne dla wszystkich chromosomów w ramach jednej
151      * instancji populacji.
152      * <p />
153      * <b>Uwaga:</b><br />
154      * Jeśli za pomocą otrzymanej referencji dojdzie do modyfikacji objektu
155      * FitnessFunction należy wykonać funkcję changed() klasy Chromosome w
156      * celu ponownego wyznaczenia wskaźnika przystosowania chromosomu.
157      * @return Referencja do obiektu.
158      * @since 1.0
159      */
160     public final ChromosomeProperties getChromosomeProperties() {
161         return this.chromosomeProperties;
162         }
163 
164     /**
165      * Zwraca refrencję do najlepszego chromosomu.
166      * @return Chromosom.
167      * @since 1.0
168      */
169     public final Chromosome getTopChromosome() {
170         return topChromosome;
171         }
172 
173     /**
174      * Wyszukuje najlepszy chromosom.
175      * @return Chromosom.
176      * @throws GeneticAlgorithmException xxx
177      * @since 1.0
178      */
179     public final Chromosome findTopChromosome()
180     throws GeneticAlgorithmException {
181         if (this.chromosomeProperties.getFitnessFunction() == null) {
182             throw new GeneticAlgorithmException(
183                new NullPointerException("fitnessFunction is null"));
184             }
185         if (this.chromosomes == null) {
186             throw new GeneticAlgorithmException(
187                new NullPointerException("chromosomes is null"));
188             }
189 
190         Chromosome top = this.getChromosomes().getFirst();
191         for (Chromosome ch : chromosomes) {
192             if (ch.compareTo(top) == 1) {
193               top = ch;
194             }
195         }
196         return top;
197         }
198 
199     /**
200      * Zwraca referencję do pojedynczego chromosomu;
201      * Uwaga; Ze względu na implementację zbioru chromosomów populacji jako
202      * listy, każdorazowo przy wywołaniu funkcji następuje przeszukanie
203      * listy od pierwszego elementu.
204      * Dla cyklicznego przetworzenia chromosow z kolekcji należy skorzystać
205      * z iteratora dostępnego w ramach LinkedList.
206      * @param i Pozycja chromosomu (0 dla pierwszego).
207      * @return Referencja do chromosomu.
208      * @since 1.0
209      */
210     public final Chromosome getChromosome(final int i) {
211         return this.chromosomes.get(i);
212         }
213 
214     /**
215      * Ustawia referencję do pojedynczego chromosomu.
216      * Uwaga; Ze względu na implementację zbioru chromosomów populacji jako
217      * listy, każdorazowo przy wywołaniu funkcji następuje przeszukanie
218      * listy od pierwszego elementu.
219      * Dla cyklicznego przetworzenia chromosow z kolekcji należy skorzystać
220      * operacji dostępnych na listach.
221      * @param i Pozycja chromosomu (0 dla pierwszego).
222      * @param chromosome Referencja do chromosomu.
223      * @since 1.0
224      */
225     public final void setChromosome(final int i, final Chromosome chromosome) {
226         this.chromosomes.set(i, chromosome);
227         }
228 
229     /**
230      * Zwraca referencję do listy chromosomów.
231      * @return Lista chromosomów.
232      * @since 1.0
233      */
234     public final LinkedList<Chromosome> getChromosomes() {
235         return this.chromosomes;
236     }
237 
238     /**
239      * Ustawia referencję do listy chromosomów.
240      * @param chromosomes Referencja do listy chromosomów.
241      * @since 1.0
242      */
243     public final void setChromosomes(final LinkedList<Chromosome> chromosomes) {
244         this.chromosomes = chromosomes;
245     }
246 
247     /**
248      * Zwraca wielkość populacji.
249      * @return Wielkość populacji.
250      * @since 1.0
251      */
252     public final int getPopulationSize() {
253         return this.chromosomes.size();
254     }
255 
256     /**
257      * Zwraca prawdopodobieństwo mutacji.
258      * @return Prawdopodobieństwo mutacji.
259      * @since 1.0
260      */
261     public final double getMutationProbability() {
262         return this.mutationProbability;
263     }
264 
265     /**
266      * Określa prawdopodobieństwo mutacji.
267      * @param mutationProbability Prawdopodobieństwo mutacji.
268      * @throws GeneticAlgorithmException xxx
269      * @since 1.0
270      */
271     public final void setMutationProbability(final double mutationProbability)
272             throws GeneticAlgorithmException {
273         if (crossoverProbability > 1 || crossoverProbability < 0) {
274             throw new GeneticAlgorithmException(new IllegalArgumentException(
275                     "Nieprawidłowa wartośc parametru "
276                     + "mutationProbability=" + mutationProbability));
277         }
278         this.mutationProbability = mutationProbability;
279     }
280 
281     /**
282      * Zwraca prawdopodobieństwo krzyżowania.
283      * @return Prawdopodobieństwo krzyżowania.
284      * @since 1.0
285      */
286     public final double getCrossoverProbability() {
287         return this.crossoverProbability;
288         }
289 
290     /**
291      * Określa prawdopodobieństwo krzyżowania.
292      * @param crossoverProbability Prawdopodobieństwo krzyżowania.
293      * @throws GeneticAlgorithmException xxx
294      * @since 1.0
295      */
296     public final void setCrossoverProbability(final double crossoverProbability)
297             throws GeneticAlgorithmException  {
298         if (crossoverProbability > 1 || crossoverProbability < 0) {
299             throw new GeneticAlgorithmException(new IllegalArgumentException(
300                     "Nieprawidłowa wartośc parametru "
301                     + "crossoverProbability=" + crossoverProbability));
302         }
303         this.crossoverProbability = crossoverProbability;
304     }
305 
306     /**
307      * Zwraca informację czy zastosowano elitaryzm.
308      * @return Elitaryzm.
309      */
310     public final boolean getElitism() {
311         return this.elitism;
312     }
313 
314     /**
315      * Ustawia elitaryzm.
316      * @param elitism Elitaryzm.
317      */
318     public final void setElitism(final boolean elitism) {
319         this.elitism = elitism;
320     }
321 
322     /**
323      * Licznik pokoleń - zwraca numer aktualnego pokolenia.
324      * @return Numer aktualnego pokolenia.
325      * @since 1.0
326      */
327     public final int getGeneration() {
328         return this.generation;
329         }
330 
331     /**
332      * Inkrementuje pokolenie.
333      * @return Numer pokolenia.
334      * @since 1.0
335      */
336     protected final int incrementGeneration() {
337         return this.generation++;
338         }
339 
340     /**
341      * Zwraca numer pokolenia w którym znaleziono najlepszy chromosom.
342      * @return Numer pokolenia.
343      * @since 1.0
344      */
345     public final int getTopChromosomeGenerationFound() {
346         return this.topChromosomeGenerationFound;
347     }
348 
349     //PARAMETRY WYMAGANE - inicjowane w konstruktorze.
350     /** Referencja do listy chromosomów. */
351     private LinkedList<Chromosome> chromosomes;
352     /** Referencja do obiektu implementującego funkcję krzyżowania. */
353     private ICrossover crossover;
354     /** Prawdopodobieństwo krzyżowania. */
355     private double crossoverProbability;
356     /**  Referencja do obiektu implementującego funkcję mutacji. */
357     private IMutation mutation;
358     /** Prawdopodobieństwo mutacji. */
359     private double mutationProbability;
360     /**
361      * Referencja do obiektu przechowującego parametry wspólne dla
362      * wszystkich chromosomów w ramach jednej instancji populacji.
363      */
364     private ChromosomeProperties chromosomeProperties;
365 
366     //PARAMETRY - inicjowane wartościami domyślnymi.
367     /** Czy uwzględnić elitaryzm. */
368     private boolean elitism = true;
369 
370     //ZMIENNE INICJOWANE W KODZIE.
371     /** Numer aktualnego pokolenia. */
372     private int generation = 0;
373     /** Numer pokolenia w którym znaleziono aktualnie najlepszy chromosom. */
374     protected int topChromosomeGenerationFound = 0;
375     /**
376      * Referencja do kopi obiektu najlepszego chromsomu.
377      * W przypadku braku elitaryzmu kopia najlepszego chromosomu może
378      * zosotać utracona.
379      **/
380     protected Chromosome topChromosome = null;
381 }