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 }