View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.math4.legacy.genetics;
18  
19  import org.apache.commons.math4.legacy.exception.DimensionMismatchException;
20  import org.apache.commons.math4.legacy.exception.MathIllegalArgumentException;
21  import org.junit.Assert;
22  import org.junit.Test;
23  
24  public class CycleCrossoverTest {
25  
26      @Test
27      public void testCrossoverExample() {
28          // taken from http://www.rubicite.com/Tutorials/GeneticAlgorithms/CrossoverOperators/CycleCrossoverOperator.aspx
29          final Integer[] p1 = new Integer[] { 8, 4, 7, 3, 6, 2, 5, 1, 9, 0 };
30          final Integer[] p2 = new Integer[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
31          final DummyListChromosome p1c = new DummyListChromosome(p1);
32          final DummyListChromosome p2c = new DummyListChromosome(p2);
33  
34          final CrossoverPolicy cp = new CycleCrossover<>();
35          final ChromosomePair pair = cp.crossover(p1c, p2c);
36  
37          final Integer[] c1 = ((DummyListChromosome) pair.getFirst()).getRepresentation().toArray(new Integer[p1.length]);
38          final Integer[] c2 = ((DummyListChromosome) pair.getSecond()).getRepresentation().toArray(new Integer[p2.length]);
39  
40          final Integer[] c1e = new Integer[] { 8, 1, 2, 3, 4, 5, 6, 7, 9, 0 };
41          final Integer[] c2e = new Integer[] { 0, 4, 7, 3, 6, 2, 5, 1, 8, 9 };
42  
43          Assert.assertArrayEquals(c1e, c1);
44          Assert.assertArrayEquals(c2e, c2);
45      }
46  
47      @Test
48      public void testCrossoverExample2() {
49          // taken from http://www.scribd.com/doc/54206412/32/Cycle-crossover
50          final Integer[] p1 = new Integer[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
51          final Integer[] p2 = new Integer[] { 9, 3, 7, 8, 2, 6, 5, 1, 4};
52          final DummyListChromosome p1c = new DummyListChromosome(p1);
53          final DummyListChromosome p2c = new DummyListChromosome(p2);
54  
55          final CrossoverPolicy cp = new CycleCrossover<>();
56          final ChromosomePair pair = cp.crossover(p1c, p2c);
57  
58          final Integer[] c1 = ((DummyListChromosome) pair.getFirst()).getRepresentation().toArray(new Integer[p1.length]);
59          final Integer[] c2 = ((DummyListChromosome) pair.getSecond()).getRepresentation().toArray(new Integer[p2.length]);
60  
61          final Integer[] c1e = new Integer[] { 1, 3, 7, 4, 2, 6, 5, 8, 9 };
62          final Integer[] c2e = new Integer[] { 9, 2, 3, 8, 5, 6, 7, 1, 4 };
63  
64          Assert.assertArrayEquals(c1e, c1);
65          Assert.assertArrayEquals(c2e, c2);
66      }
67  
68      @Test
69      public void testCrossover() {
70          final Integer[] p1 = new Integer[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
71          final Integer[] p2 = new Integer[] { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
72          final DummyListChromosome p1c = new DummyListChromosome(p1);
73          final DummyListChromosome p2c = new DummyListChromosome(p2);
74  
75          final CrossoverPolicy cp = new CycleCrossover<Integer>(true);
76  
77          for (int i = 0; i < 20; i++) {
78              final ChromosomePair pair = cp.crossover(p1c, p2c);
79  
80              final Integer[] c1 = ((DummyListChromosome) pair.getFirst()).getRepresentation().toArray(new Integer[p1.length]);
81              final Integer[] c2 = ((DummyListChromosome) pair.getSecond()).getRepresentation().toArray(new Integer[p2.length]);
82  
83              int index = 0;
84              // Determine if it is in the same spot as in the first parent, if
85              // not it comes from the second parent.
86              for (final Integer j : c1) {
87                  if (!p1[index].equals(j)) {
88                      Assert.assertEquals(j, p2[index]);
89                  } else {
90                      Assert.assertEquals(j, p1[index]);
91                  }
92                  index++;
93              }
94  
95              // Same as above only for the second parent.
96              index = 0;
97              for (final Integer k : c2) {
98                  if (p2[index] != k) {
99                      Assert.assertEquals(k, p1[index]);
100                 } else {
101                     Assert.assertEquals(k, p2[index]);
102                 }
103                 index++;
104             }
105         }
106     }
107 
108     @Test(expected = DimensionMismatchException.class)
109     public void testCrossoverDimensionMismatchException() {
110         final Integer[] p1 = new Integer[] { 1, 0, 1, 0, 0, 1, 0, 1, 1 };
111         final Integer[] p2 = new Integer[] { 0, 1, 1, 0, 1 };
112 
113         final BinaryChromosome p1c = new DummyBinaryChromosome(p1);
114         final BinaryChromosome p2c = new DummyBinaryChromosome(p2);
115 
116         final CrossoverPolicy cp = new CycleCrossover<>();
117         cp.crossover(p1c, p2c);
118     }
119 
120     @Test(expected = MathIllegalArgumentException.class)
121     public void testCrossoverInvalidFixedLengthChromosomeFirst() {
122         final Integer[] p1 = new Integer[] { 1, 0, 1, 0, 0, 1, 0, 1, 1 };
123         final BinaryChromosome p1c = new DummyBinaryChromosome(p1);
124         final Chromosome p2c = new Chromosome() {
125             @Override
126             public double fitness() {
127                 // Not important
128                 return 0;
129             }
130         };
131 
132         final CrossoverPolicy cp = new CycleCrossover<>();
133         cp.crossover(p1c, p2c);
134     }
135 
136     @Test(expected = MathIllegalArgumentException.class)
137     public void testCrossoverInvalidFixedLengthChromosomeSecond() {
138         final Integer[] p1 = new Integer[] { 1, 0, 1, 0, 0, 1, 0, 1, 1 };
139         final BinaryChromosome p2c = new DummyBinaryChromosome(p1);
140         final Chromosome p1c = new Chromosome() {
141             @Override
142             public double fitness() {
143                 // Not important
144                 return 0;
145             }
146         };
147 
148         final CrossoverPolicy cp = new CycleCrossover<>();
149         cp.crossover(p1c, p2c);
150     }
151 }