View Javadoc
1   /**
2    * @(#)SwapMutation.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.mutation;
10  
11  import com.delhezi.ga.Chromosome;
12  import java.util.Random;
13  import java.util.logging.Logger;
14  
15  /**
16   * Klasa <code>SwapMutation</code>: Mutacja przez zamianę miejscami
17   * Swap Mutation (SM).
18   * @version 1.0 2009-06-10
19   * @author <a href="mailto:wojciech.wolszczak@delhezi.com">
20   * Wojciech Wolszczak</a>
21   */
22  public class SwapMutation implements IMutation {
23  
24      /** Logger object. */
25      private static final Logger LOGGER =
26          Logger.getLogger(SwapMutation.class.getName());
27  
28      /** Delhezi Error Code. */
29      //private static final String DERC = "1-6-2-";
30      
31      /** Class name. */
32      private static final String CLASS_NAME = SwapMutation.class.getName();
33  
34      /**
35       * Random.
36       */
37      private static Random random = new Random();
38  
39      /**
40       * Funkcja mutation implementuje mutację przez zamianę miejscami
41       * dwóch wylosowanych genów.
42       * @param chromosome Chromosom podlegający mutacji.
43       * @since 1.0
44       */
45      public final void mutation(final Chromosome chromosome) {
46          LOGGER.entering(CLASS_NAME, "mutation", chromosome);
47        
48          if (chromosome == null) {
49              throw new IllegalArgumentException("Chromosome is null.");
50              }
51          int chromosomeSize  = chromosome.size();
52          //Chromosom ma tylko 1 gen.
53          if (chromosomeSize < 2) {
54              return;
55              }
56  
57          //Losuje liczny z zakresu od 0 do chromosomeSize.
58          int gene1 = (int) (random.nextDouble() * chromosomeSize);
59          int gene2 = (int) (random.nextDouble() * chromosomeSize);
60  
61          //Korekta wyniku.
62          //Istnieje bardzo małe prawdopodobienstwo wylosowania liczby o
63          //wartosci chromosomeSize (poza zakresem), np. 4.999999999999999
64          //zaokraglane jest do 4, ale sprawdzę:
65          if (gene1 == chromosomeSize) {
66              gene1--;
67          }
68          if (gene2 == chromosomeSize) {
69              gene2--;
70          }
71  
72          this.mutation(chromosome, gene1, gene2);
73  
74          LOGGER.exiting(CLASS_NAME, "mutation",
75                         new Object[] { chromosome, gene1, gene2 });
76      }
77  
78      /**
79       * Funkcja mutation implementuje mutację przez zamianę miejscami
80       * dwóch wylosowanych genów.
81       * @param chromosome Chromosom podlegający mutacji.
82       * @param gene1 Gen podlegający zamianie. Przykład: gene1=1 dla xXxxxxxx.
83       * @param gene2 Gen podlegający zamianie. Przykład: gene2=0 dla Xxxxxxxx.
84       * @since 1.0
85       */
86      protected final void mutation(final Chromosome chromosome,
87                                    final int gene1,
88                                    final int gene2) {
89          LOGGER.entering(CLASS_NAME, "mutation",
90                          new Object[] { chromosome, gene1, gene2 });
91  
92        //Chromosom nie może być wartością null.
93        assert chromosome != null : "Illegal argument chromosome: null";
94  
95        int chromosomeSize = chromosome.size();
96  
97        //Punkt gene1 powinien zawierać się w obszare chromosomu.
98        assert (gene1 >= 0 && gene1 < chromosomeSize)
99           : "Illegal argument gene1: " + gene1;
100       //Punkt gene2 powinien zawierać się w obszare chromosomu.
101       assert (gene2 >= 0 && gene2 < chromosomeSize)
102           : "Illegal argument gene2: " + gene2;
103 
104       //W przypadku kiedy gen1 i gen2 są tymi samymi genami mutacja przez
105       //zamianę miejscami nie spowoduje żadnych zmian.
106       if (gene1 == gene2) {
107           return;
108           }
109 
110       Object temp = chromosome.getGene(gene1);
111       chromosome.setGene(gene1, chromosome.getGene(gene2));
112       chromosome.setGene(gene2, temp);
113 
114         //Zasygnalizuj, ze chromosom został zmieniony.
115         chromosome.changed();
116         
117         LOGGER.exiting(CLASS_NAME, "mutation", chromosome);
118     }
119 }