View Javadoc
1   package net.bmahe.genetics4j.neat.mutation.chromosome;
2   
3   import java.util.ArrayList;
4   import java.util.List;
5   import java.util.Objects;
6   import java.util.random.RandomGenerator;
7   
8   import org.apache.commons.collections4.CollectionUtils;
9   import org.apache.commons.lang3.Validate;
10  import org.apache.logging.log4j.LogManager;
11  import org.apache.logging.log4j.Logger;
12  
13  import net.bmahe.genetics4j.core.chromosomes.Chromosome;
14  import net.bmahe.genetics4j.core.mutation.chromosome.ChromosomeMutationHandler;
15  import net.bmahe.genetics4j.core.spec.chromosome.ChromosomeSpec;
16  import net.bmahe.genetics4j.core.spec.mutation.MutationPolicy;
17  import net.bmahe.genetics4j.neat.Connection;
18  import net.bmahe.genetics4j.neat.ImmutableConnection;
19  import net.bmahe.genetics4j.neat.chromosomes.NeatChromosome;
20  import net.bmahe.genetics4j.neat.spec.NeatChromosomeSpec;
21  
22  public abstract class AbstractNeatChromosomeConnectionMutationHandler<T>
23  		implements ChromosomeMutationHandler<NeatChromosome>
24  {
25  	public final Logger logger = LogManager.getLogger(this.getClass());
26  
27  	private final Class<T> mutationClazz;
28  	private final RandomGenerator randomGenerator;
29  
30  	protected abstract List<Connection> mutateConnection(final T mutationPolicy, final NeatChromosome neatChromosome,
31  			final Connection oldConnection, final int i);
32  
33  	protected Class<T> getMutationClazz() {
34  		return mutationClazz;
35  	}
36  
37  	protected RandomGenerator getRandomGenerator() {
38  		return randomGenerator;
39  	}
40  
41  	protected AbstractNeatChromosomeConnectionMutationHandler(final Class<T> _mutationClazz,
42  			final RandomGenerator _randomGenerator) {
43  		Objects.requireNonNull(_mutationClazz);
44  		Objects.requireNonNull(_randomGenerator);
45  
46  		this.mutationClazz = _mutationClazz;
47  		this.randomGenerator = _randomGenerator;
48  	}
49  
50  	@Override
51  	public boolean canHandle(final MutationPolicy mutationPolicy, final ChromosomeSpec chromosome) {
52  		Objects.requireNonNull(mutationPolicy);
53  		Objects.requireNonNull(chromosome);
54  
55  		return mutationClazz.isInstance(mutationPolicy) && chromosome instanceof NeatChromosomeSpec;
56  	}
57  
58  	@Override
59  	public NeatChromosome mutate(final MutationPolicy mutationPolicy, final Chromosome chromosome) {
60  		Objects.requireNonNull(mutationPolicy);
61  		Objects.requireNonNull(chromosome);
62  		Validate.isInstanceOf(mutationClazz, mutationPolicy);
63  		Validate.isInstanceOf(NeatChromosome.class, chromosome);
64  
65  		final var neatChromosome = (NeatChromosome) chromosome;
66  
67  		final var minValue = neatChromosome.getMinWeightValue();
68  		final var maxValue = neatChromosome.getMaxWeightValue();
69  
70  		final var oldConnections = neatChromosome.getConnections();
71  		final List<Connection> newConnections = new ArrayList<>();
72  
73  		if (CollectionUtils.isNotEmpty(oldConnections)) {
74  
75  			final int alleleFlipIndex = randomGenerator.nextInt(oldConnections.size());
76  
77  			int i = 0;
78  			/**
79  			 * Copy every connection prior to the alleleFlipIndex
80  			 */
81  			while (i < alleleFlipIndex) {
82  				final var connection = oldConnections.get(i);
83  				final var newConnection = ImmutableConnection.copyOf(connection);
84  				newConnections.add(newConnection);
85  
86  				i++;
87  			}
88  
89  			/**
90  			 * Pick a random weight
91  			 */
92  			final var oldConnection = oldConnections.get(i);
93  			final var mutatedConnection = mutateConnection(
94  					mutationClazz.cast(mutationPolicy),
95  					neatChromosome,
96  					oldConnection,
97  					i);
98  			newConnections.addAll(mutatedConnection);
99  			i++;
100 
101 			/**
102 			 * Copy every connection after to the alleleFlipIndex
103 			 */
104 			while (i < oldConnections.size()) {
105 				final var connection = oldConnections.get(i);
106 				final var newConnection = ImmutableConnection.copyOf(connection);
107 				newConnections.add(newConnection);
108 
109 				i++;
110 			}
111 
112 		}
113 
114 		return new NeatChromosome(neatChromosome.getNodeLayout(), minValue, maxValue, newConnections);
115 	}
116 }