View Javadoc
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 }