1 /**
2 * @(#)GeneticAlgorithm.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.factory.CrossoverFactory;
12 import com.delhezi.ga.crossover.factory.CrossoverOperatorType;
13 import com.delhezi.ga.exception.GeneticAlgorithmException;
14 import com.delhezi.ga.fitnessfunction.drivers.ScriptEngineDriver;
15 import com.delhezi.ga.fitnessfunction.FitnessFunctionOption;
16 import com.delhezi.ga.mutation.factory.MutationFactory;
17 import com.delhezi.ga.mutation.factory.MutationOperatorType;
18 import com.delhezi.ga.selection.factory.SelectionFactory;
19 import com.delhezi.ga.selection.factory.SelectionMethodType;
20 import com.delhezi.ga.fitnessfunction.FitnessFunction;
21 import com.delhezi.ga.fitnessfunction.drivers.IFitnessFunctionDriver;
22 import com.delhezi.ga.fitnessfunction.drivers.factory.FitnessFunctionDriverFactory;
23 //import java.util.logging.Logger;
24
25 /**
26 * <code>GeneticAlgorithm</code>: Fasada.
27 * @version 1.0 2011-01-25
28 * @author <a href="mailto:wojciech.wolszczak@delhezi.com">
29 * Wojciech Wolszczak</a>
30 */
31 public class GeneticAlgorithm {
32 /** Logger object. */
33 // private static final Logger LOGGER =
34 // Logger.getLogger(GeneticAlgorithm.class.getName());
35
36 /** Delhezi Error Code. */
37 // private static final String DERC = "1-3-";
38
39 private Population population;
40
41 private State stateError;
42 private State stateInitialized;
43 private State stateRunning;
44 private State stateStopped;
45 private State state;
46
47 /**
48 * Konstruktor.
49 * @since 1.0
50 */
51 public GeneticAlgorithm() {
52 stateError = new StateError(this);
53 stateInitialized = new StateInitialized(this);
54 stateRunning = new StateRunning(this);
55 stateStopped = new StateStopped(this);
56 state = null;
57 }
58
59 /**
60 * Licznik pokoleń - zwraca numer aktualnego pokolenia.
61 * @return Numer aktualnego pokolenia.
62 * @since 1.0
63 */
64 public int getGeneration() {
65 return getPopulation().getGeneration();
66 }
67
68 /**
69 * Zwraca wartość wskaźnika przystosowania najlepszego chromosomu.
70 * @return Wartość wskaźnika przystosowania najlepszego chromosomu.
71 * @throws GeneticAlgorithmException xxx
72 * @since 1.0
73 */
74 public double getTopChromosomeCost() throws GeneticAlgorithmException {
75 return getPopulation().getTopChromosome().getFitness();
76 }
77
78 /**
79 * Zwraca numer pokolenia w którym znaleziono najlepszy chromosom.
80 * @return Numer pokolenia.
81 * @since 1.0
82 */
83 public int getTopChromosomeGenerationFound() {
84 return getPopulation().getTopChromosomeGenerationFound();
85 }
86
87 /**
88 * Zwraca typ populacji.
89 * @return Typ populacji.
90 * @since 1.0
91 */
92 public PopulationType getPopulationType() {
93 PopulationType popType = null;
94 if (getPopulation().getClass().getName().equals("com.delhezi.ga.PopulationChangeableSize")) {
95 popType = PopulationType.valueOf("PopulationChangeableSize");
96 } else if (getPopulation().getClass().getName().equals("com.delhezi.ga.PopulationConstantSize")) {
97 popType = PopulationType.valueOf("PopulationConstantSize");
98 }
99 return popType;
100 }
101
102 /**
103 * Przekszta populację na populację o stałej liczebności;
104 * Funkcja określona dla populacji o zmiennej liczebności;
105 * W przypadku użycia dla populacji o stałej liczbności zwraca wyjątek GeneticAlgorithmException.
106 * @param selectionMethod Typ funkcji celu.
107 * @throws GeneticAlgorithmException If getPopulationType() != PopulationType.PopulationChangeableSize.
108 * @since 1.0
109 */
110 public void toPopulationConstantSize(SelectionMethodType selectionMethod) throws GeneticAlgorithmException {
111 if (getPopulationType() == PopulationType.PopulationChangeableSize) {
112 setPopulation(((com.delhezi.ga.PopulationChangeableSize)getPopulation()).toPopulationConstantSize(selectionMethod));
113 } else {
114 throw new GeneticAlgorithmException("Funkcja określona dla PopulationType.PopulationChangeableSize");
115 }
116 }
117
118 /**
119 * Przekształca populację na populację o zmiennej liczebności;
120 * Funkcja określona dla populacji o stałej liczebności;
121 * W przypadku użycia dla populacji o zmiennej liczbności zwraca wyjątek GeneticAlgorithmException.
122 * @param maxLT Maksymalny czas życia dopuszczalny dla chromosomu.
123 * @param minLT Minimalny czas życia dopuszczalny dla chromosomu.
124 * @throws GeneticAlgorithmException If getPopulationType() != PopulationType.PopulationConstantSize.
125 * @since 1.0
126 */
127 public void toPopulationChangeableSize(int maxLT,
128 int minLT) throws GeneticAlgorithmException {
129 if (getPopulationType() == PopulationType.PopulationConstantSize) {
130 setPopulation(((com.delhezi.ga.PopulationConstantSize)getPopulation()).toPopulationChangeableSize(maxLT,
131 minLT));
132 } else {
133 throw new GeneticAlgorithmException("Funkcja określona dla PopulationType.PopulationConstantSize");
134 }
135 }
136
137 /**
138 * Zwraca maksymalny czas życia dopuszczalny dla chromosomu;
139 * Funkcja określona dla populacji o zmiennej liczebności;
140 * W przypadku użycia dla populacji o stałej liczbności zwraca wyjątek GeneticAlgorithmException.
141 * @return Maksymalny czas życia dopuszczalny dla chromosomu.
142 * @throws GeneticAlgorithmException If getPopulationType() != PopulationType.PopulationChangeableSize.
143 * @since 1.0
144 */
145 public int getMaxLT() throws GeneticAlgorithmException {
146 if (getPopulationType() == PopulationType.PopulationChangeableSize) {
147 return ((com.delhezi.ga.PopulationChangeableSize) getPopulation()).getMaxLT();
148 } else {
149 throw new GeneticAlgorithmException("Parametr zdefiniowany dla PopulationType.PopulationChangeableSize");
150 }
151 }
152
153 /**
154 * Ustawia maksymalny czas życia dopuszczalny dla chromosomu;
155 * Funkcja określona dla populacji o zmiennej liczebności;
156 * W przypadku użycia dla populacji o stałej liczbności zwraca wyjątek GeneticAlgorithmException.
157 * @param maxLT Maksymalny czas życia dopuszczalny dla chromosomu.
158 * @throws GeneticAlgorithmException If getPopulationType() != PopulationType.PopulationChangeableSize.
159 * @since 1.0
160 */
161 public void setMaxLT(int maxLT) throws GeneticAlgorithmException {
162 if (getPopulationType() == PopulationType.PopulationChangeableSize) {
163 ((com.delhezi.ga.PopulationChangeableSize) getPopulation()).setMaxLT(maxLT);
164 } else {
165 throw new GeneticAlgorithmException("Parametr zdefiniowany dla PopulationType.PopulationChangeableSize");
166 }
167 }
168
169 /**
170 * Zwraca minimalny czas życia dopuszczalny dla chromosomu;
171 * Funkcja określona dla populacji o zmiennej liczebności;
172 * W przypadku użycia dla populacji o stałej liczbności zwraca wyjątek GeneticAlgorithmException.
173 * @return Minimalny czas życia dopuszczalny dla chromosomu.
174 * @throws GeneticAlgorithmException If getPopulationType() != PopulationType.PopulationChangeableSize.
175 * @since 1.0
176 */
177 public int getMinLT() throws GeneticAlgorithmException {
178 if (getPopulationType() == PopulationType.PopulationChangeableSize) {
179 return ((com.delhezi.ga.PopulationChangeableSize) getPopulation()).getMinLT();
180 } else {
181 throw new GeneticAlgorithmException("Parametr zdefiniowany dla PopulationType.PopulationChangeableSize");
182 }
183 }
184
185 /**
186 * Ustawia minimalny czas życia dopuszczalny dla chromosomu;
187 * Funkcja określona dla populacji o zmiennej liczebności;
188 * W przypadku użycia dla populacji o stałej liczbności zwraca wyjątek GeneticAlgorithmException.
189 * @param minLT Minimalny czas życia dopuszczalny dla chromosomu.
190 * @throws GeneticAlgorithmException If getPopulationType() != PopulationType.PopulationChangeableSize.
191 * @since 1.0
192 */
193 public void setMinLT(int minLT) throws GeneticAlgorithmException {
194 if (getPopulationType() == PopulationType.PopulationChangeableSize) {
195 ((com.delhezi.ga.PopulationChangeableSize) getPopulation()).setMinLT(minLT);
196 } else {
197 throw new GeneticAlgorithmException("Parametr zdefiniowany dla PopulationType.PopulationChangeableSize");
198 }
199 }
200
201 /**
202 * Zwraca typ funkcji selekcji;
203 * Funkcja określona dla populacji o stałej liczebności;
204 * W przypadku użycia dla populacji o zmiennej liczbności zwraca wyjątek GeneticAlgorithmException.
205 * @return Typ funkcji selekcji.
206 * @throws GeneticAlgorithmException If getPopulationType() != PopulationType.PopulationConstantSize.
207 * @since 1.0
208 */
209 public SelectionMethodType getSelectionMethod() throws GeneticAlgorithmException {
210 if (getPopulationType() == PopulationType.PopulationConstantSize) {
211 return SelectionFactory.getSelectionMethodType(((com.delhezi.ga.PopulationConstantSize) getPopulation()).getSelect());
212 } else {
213 throw new GeneticAlgorithmException("Parametr zdefiniowany dla PopulationType.PopulationConstantSize");
214 }
215 }
216
217 /**
218 * Ustawia funkcję selekcji;
219 * Funkcja określona dla populacji o stałej liczebności;
220 * W przypadku użycia dla populacji o zmiennej liczbności zwraca wyjątek GeneticAlgorithmException.
221 * @param selectionMethod Typ funkcji selekcji.
222 * @throws GeneticAlgorithmException If getPopulationType() != PopulationType.PopulationConstantSize.
223 * @since 1.0
224 */
225 public void setSelectionMethod(SelectionMethodType selectionMethod) throws GeneticAlgorithmException {
226 if (getPopulationType() == PopulationType.PopulationConstantSize) {
227 ((com.delhezi.ga.PopulationConstantSize) getPopulation()).setSelect(selectionMethod);
228 } else {
229 throw new GeneticAlgorithmException("Parametr zdefiniowany dla PopulationType.PopulationConstantSize");
230 }
231 }
232
233 /**
234 * Zwraca typ operatora krzyżowania.
235 * @return Typ operatora krzyżowania.
236 * @throws GeneticAlgorithmException xxx
237 * @since 1.0
238 */
239 public CrossoverOperatorType getCrossoverOperator() throws GeneticAlgorithmException {
240 return CrossoverFactory.getCrossoverOperatorType(getPopulation().getCrossover());
241 }
242
243 /**
244 * Ustawia operator krzyżowania.
245 * @param crossoverOperator Typ operatora krzyżowania.
246 * @throws GeneticAlgorithmException xxx
247 * @since 1.0
248 */
249 public void setCrossoverOperator(CrossoverOperatorType crossoverOperator) throws GeneticAlgorithmException {
250 getPopulation().setCrossover(crossoverOperator);
251 }
252
253 /**
254 * Zwraca prawdopodobieństwo krzyżowania.
255 * @return Prawdopodobieństwo krzyżowania.
256 * @since 1.0
257 */
258 public double getCrossoverProbability() {
259 return getPopulation().getCrossoverProbability();
260 }
261
262 /**
263 * Ustawia prawdopodobieństwo krzyżowania.
264 * @param crossoverProbability Prawdopodobieństwo krzyżowania.
265 * @throws GeneticAlgorithmException xxx
266 * @since 1.0
267 */
268 public void setCrossoverProbability(double crossoverProbability) throws GeneticAlgorithmException {
269 getPopulation().setCrossoverProbability(crossoverProbability);
270 }
271
272 /**
273 * Zwraca typ operatora mutacji.
274 * @return Typ operatora mutacji.
275 * @throws GeneticAlgorithmException xxx
276 * @since 1.0
277 */
278 public MutationOperatorType getMutationOperator() throws GeneticAlgorithmException {
279 return MutationFactory.getMutationOperatorType(getPopulation().getMutation());
280 }
281
282 /**
283 * Ustawia operator mutacji.
284 * @param mutationOperator Typ operatora mutacji.
285 * @throws GeneticAlgorithmException xxx
286 * @since 1.0
287 */
288 public void setMutationOperator(MutationOperatorType mutationOperator) throws GeneticAlgorithmException {
289 getPopulation().setMutation(mutationOperator);
290 }
291
292 /**
293 * Zwraca prawdopodobieństwo mutacji.
294 * @return Prawdopodobieństwo mutacji.
295 * @since 1.0
296 */
297 public double getMutationProbability() {
298 return getPopulation().getMutationProbability();
299 }
300
301 /**
302 * Ustawia prawdopodobieństwo mutacji.
303 * @param mutationProbability Prawdopodobieństwo mutacji.
304 * @throws GeneticAlgorithmException xxx
305 * @since 1.0
306 */
307 public void setMutationProbability(double mutationProbability) throws GeneticAlgorithmException {
308 getPopulation().setMutationProbability(mutationProbability);
309 }
310
311 /**
312 * Zwraca informację czy zastosowano elitaryzm.
313 * @return Elitaryzm.
314 * @since 1.0
315 */
316 public boolean getElitism() {
317 return getPopulation().getElitism();
318 }
319
320 /**
321 * Ustawia elitaryzm.
322 * @param elitism Elitaryzm.
323 * @since 1.0
324 */
325 public void setElitism(boolean elitism) {
326 getPopulation().setElitism(elitism);
327 }
328
329 /**
330 * Zwraca bezwzględną ścieżkę do katalogu w którym składowane są skrytpy
331 * funkcji celu.
332 * @return Ścieżka do katalogu.
333 * @since 1.0
334 */
335 public String getFitnessFunctionScriptPath() {
336 return ((ScriptEngineDriver) getPopulation().getChromosomeProperties().getFitnessFunction().getScriptEngineDriver()).getScriptPath();
337 }
338
339 /**
340 * Zwraca nazwę pliku z używanym skrytem funkcji celu.
341 * @return Nazwa pliku ze skrytem funkcji celu.
342 * @since 1.0
343 */
344 public String getFitnessFunctionScriptFile() {
345 return ((ScriptEngineDriver) getPopulation().getChromosomeProperties().getFitnessFunction().getScriptEngineDriver()).getScriptFile();
346 }
347
348 /**
349 * Zwraca nazwę silnika skryptów.
350 * @return Nazwa silnika skryptów.
351 * @since 1.0
352 */
353 public String getFitnessFunctionEnginName() {
354 return ((ScriptEngineDriver) getPopulation().getChromosomeProperties().getFitnessFunction().getScriptEngineDriver()).getScriptEnginName();
355 }
356
357 /**
358 * Zwraca informację o maksymalizacji/maksymalizacji funkcji celu.
359 * @return Informacja o maksymalizacji/maksymalizacji funkcji celu.
360 * @since 1.0
361 */
362 public FitnessFunctionOption getFitnessFunctionOption() {
363 return (getPopulation().getChromosomeProperties().getFitnessFunction().isMaximisation() ==
364 true) ? FitnessFunctionOption.maximisation :
365 FitnessFunctionOption.minimisation;
366 }
367
368 /**
369 * Ustawia informację o maksymalizacji/maksymalizacji funkcji celu.
370 * @param fitnessFunctionOption Maksymalizacja/maksymalizacja funkcji celu.
371 * @throws GeneticAlgorithmException xxx
372 * @since 1.0
373 */
374 public void setFitnessFunctionOption(FitnessFunctionOption fitnessFunctionOption) throws GeneticAlgorithmException {
375 FitnessFunction fitnessFunction =
376 getPopulation().getChromosomeProperties().getFitnessFunction();
377 if (fitnessFunctionOption == FitnessFunctionOption.minimisation) {
378 fitnessFunction.setMaximisation(false);
379 } else if (fitnessFunctionOption == FitnessFunctionOption.maximisation) {
380 fitnessFunction.setMaximisation(true);
381 }
382 }
383
384 /**
385 * Ustawia funkcję celu.
386 * @param fitnessFunctionEnginName Nazwa silnika skryptów. Przykładowe
387 * wartości: [js, rhino, JavaScript, javascript, ECMAScript, ecmascript].
388 * @param fitnassFunctionScriptsPath Bezwzględna ścieżkę do katalogu w
389 * którym składowane są skrytpy funkcji celu.
390 * @param fitnessFunctionScriptFile Nazwa pliku ze skrytem funkcji celu.
391 * @param fitnessFunctionOption Maksymalizacja/maksymalizacja funkcji celu.
392 * @throws GeneticAlgorithmException xxx
393 * @since 1.0
394 */
395 public void setFitnessFunction(String fitnessFunctionEnginName,
396 String fitnassFunctionScriptsPath,
397 String fitnessFunctionScriptFile,
398 FitnessFunctionOption fitnessFunctionOption) throws GeneticAlgorithmException {
399 IFitnessFunctionDriver fitnessFunctionDriver =
400 FitnessFunctionDriverFactory.getFitnessFunctionEngineDriver(fitnessFunctionEnginName,
401 fitnassFunctionScriptsPath,
402 fitnessFunctionScriptFile);
403 FitnessFunction fitnessFunction =
404 new FitnessFunction(fitnessFunctionDriver, "fitnessFunction");
405 if (fitnessFunctionOption == FitnessFunctionOption.minimisation) {
406 fitnessFunction.setMaximisation(false);
407 } else if (fitnessFunctionOption == FitnessFunctionOption.maximisation) {
408 fitnessFunction.setMaximisation(true);
409 }
410 getPopulation().getChromosomeProperties().setFitnessFunction(fitnessFunction);
411 }
412
413 /**
414 * Zwraca wielkość populacji.
415 * @return Wielkość populacji.
416 * @since 1.0
417 */
418 public int getPopulationSize() {
419 return getPopulation().getPopulationSize();
420 }
421
422 /**
423 * Ustawia wielkość populacji;
424 * Funkcja określona dla populacji o stałej liczebności;
425 * W przypadku użycia dla populacji o zmiennej liczbności zwraca wyjątek GeneticAlgorithmException.
426 * @param populationSize Wielkość populacji.
427 * @throws GeneticAlgorithmException If getPopulationType() != PopulationType.PopulationConstantSize.
428 * @since 1.0
429 */
430 public void setPopulationSize(int populationSize) throws GeneticAlgorithmException {
431 if (getPopulationType() == PopulationType.PopulationConstantSize) {
432 ((com.delhezi.ga.PopulationConstantSize) getPopulation()).changePopulationSize(populationSize);
433 } else {
434 throw new GeneticAlgorithmException("Metoda zdefiniowana dla PopulationType.PopulationConstantSize");
435 }
436 }
437
438 /**
439 * Uruchamia algorytm genetyczny.
440 * @throws GeneticAlgorithmException xxx
441 */
442 public void run() throws GeneticAlgorithmException {
443 state.run();
444 }
445
446 /**
447 * Zatrzymuje działanie algorytmu genetycznego.
448 * @throws GeneticAlgorithmException xxx
449 */
450 public void stop() throws GeneticAlgorithmException {
451 state.stop();
452 }
453
454 /**
455 * Warunki końca.
456 * opcjonalne parametry - inicjowane wartościami 0.
457 * Parametry uzwględniane w sterowaniu jeśli ich wartość jest większa niż 0.
458 */
459 private int maxGenerationCount = 0;
460 private int lastGenerationTopChromosomeFind = 0;
461
462 /**
463 * Warunek końca; Zwraca maksymalną ilość przewidzianych generacji.
464 * @return Maksymalna ilość przewidzianych generacji.
465 */
466 public int getMaxGenerationCount() {
467 return this.maxGenerationCount;
468 }
469
470 /**
471 * Warunek końca; Ustawia maksymalną ilość przewidzianych generacji.
472 * @param maxGenerationCount Maksymalna ilość przewidzianych generacji.
473 */
474 public void setMaxGenerationCount(int maxGenerationCount) {
475 this.maxGenerationCount = maxGenerationCount;
476 }
477
478 /**
479 * Warunek końca; Zwraca maksymalną ilość przewidzianych generacji od
480 * chwili znalezienia ostatniego najlepszego chromosomu.
481 * @return Maksymalna ilość przewidzianych generacji.
482 */
483 public int getLastGenerationTopChromosomeFind() {
484 return this.lastGenerationTopChromosomeFind;
485 }
486
487 /**
488 * Warunek końca; Ustawia maksymalną ilość przewidzianych generacji od
489 * chwili znalezienia ostatniego najlepszego chromosomu.
490 * @param lastGenerationTopChromosomeFind Maksymalna ilość przewidzianych generacji.
491 */
492 public void setLastGenerationTopChromosomeFind(int lastGenerationTopChromosomeFind) {
493 this.lastGenerationTopChromosomeFind = lastGenerationTopChromosomeFind;
494 }
495
496 /**
497 * Zwraca stan algorytmu genetycznego.
498 * @return Stan.
499 * @since 1.0
500 */
501 public GeneticAlgorithmState getState() {
502 return state.getState();
503 }
504
505 /**
506 * Ustawia stan algorytmu genetycznego.
507 * @param state Stan.
508 * @since 1.0
509 */
510 protected void setState(final GeneticAlgorithmState state) {
511 switch (state) {
512 case ERROR:
513 this.state = stateError;
514 break;
515 case STOPPED:
516 this.state = stateStopped;
517 break;
518 case RUNNING:
519 this.state = stateRunning;
520 break;
521 case INITIALIZED:
522 this.state = stateInitialized;
523 break;
524 }
525 }
526
527 /**
528 * Zwraca referencję do populacji.
529 * @return Referencja do populacji.
530 * @since 1.0
531 */
532 protected Population getPopulation() {
533 return this.population;
534 }
535
536 /**
537 * Ustawia populację.
538 * @param population Populacja.
539 * @since 1.0
540 */
541 protected void setPopulation(Population population) {
542 this.population = population;
543 }
544 }