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 }