/*
* Encog(tm) Core v3.3 - Java Version
* http://www.heatonresearch.com/encog/
* https://github.com/encog/encog-java-core
* Copyright 2008-2014 Heaton Research, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* For more information on Heaton Research copyrights, licenses
* and trademarks visit:
* http://www.heatonresearch.com/copyright
*/
package org.encog.neural.neat;
import org.encog.ml.CalculateScore;
import org.encog.ml.ea.opp.CompoundOperator;
import org.encog.ml.ea.opp.selection.TruncationSelection;
import org.encog.ml.ea.train.basic.TrainEA;
import org.encog.neural.hyperneat.HyperNEATCODEC;
import org.encog.neural.neat.training.opp.NEATCrossover;
import org.encog.neural.neat.training.opp.NEATMutateAddLink;
import org.encog.neural.neat.training.opp.NEATMutateAddNode;
import org.encog.neural.neat.training.opp.NEATMutateRemoveLink;
import org.encog.neural.neat.training.opp.NEATMutateWeights;
import org.encog.neural.neat.training.opp.links.MutatePerturbLinkWeight;
import org.encog.neural.neat.training.opp.links.MutateResetLinkWeight;
import org.encog.neural.neat.training.opp.links.SelectFixed;
import org.encog.neural.neat.training.opp.links.SelectProportion;
import org.encog.neural.neat.training.species.OriginalNEATSpeciation;
/**
* NEAT does not make use of a special trainer. Typically the generic TrainEA
* trainer is used. This utility class creates a NEAT compatible TrainEA class.
*
* -----------------------------------------------------------------------------
* http://www.cs.ucf.edu/~kstanley/ Encog's NEAT implementation was drawn from
* the following three Journal Articles. For more complete BibTeX sources, see
* NEATNetwork.java.
*
* Evolving Neural Networks Through Augmenting Topologies
*
* Generating Large-Scale Neural Networks Through Discovering Geometric
* Regularities
*
* Automatic feature selection in neuroevolution
*/
public class NEATUtil {
public static TrainEA constructNEATTrainer(
final CalculateScore calculateScore, final int inputCount,
final int outputCount, final int populationSize) {
final NEATPopulation pop = new NEATPopulation(inputCount, outputCount,
populationSize);
pop.reset();
return constructNEATTrainer(pop, calculateScore);
}
/**
* Construct a NEAT (or HyperNEAT trainer.
* @param population The population.
* @param calculateScore The score function.
* @return The NEAT EA trainer.
*/
public static TrainEA constructNEATTrainer(final NEATPopulation population,
final CalculateScore calculateScore) {
final TrainEA result = new TrainEA(population, calculateScore);
result.setSpeciation(new OriginalNEATSpeciation());
result.setSelection(new TruncationSelection(result, 0.3));
final CompoundOperator weightMutation = new CompoundOperator();
weightMutation.getComponents().add(
0.1125,
new NEATMutateWeights(new SelectFixed(1),
new MutatePerturbLinkWeight(0.02)));
weightMutation.getComponents().add(
0.1125,
new NEATMutateWeights(new SelectFixed(2),
new MutatePerturbLinkWeight(0.02)));
weightMutation.getComponents().add(
0.1125,
new NEATMutateWeights(new SelectFixed(3),
new MutatePerturbLinkWeight(0.02)));
weightMutation.getComponents().add(
0.1125,
new NEATMutateWeights(new SelectProportion(0.02),
new MutatePerturbLinkWeight(0.02)));
weightMutation.getComponents().add(
0.1125,
new NEATMutateWeights(new SelectFixed(1),
new MutatePerturbLinkWeight(1)));
weightMutation.getComponents().add(
0.1125,
new NEATMutateWeights(new SelectFixed(2),
new MutatePerturbLinkWeight(1)));
weightMutation.getComponents().add(
0.1125,
new NEATMutateWeights(new SelectFixed(3),
new MutatePerturbLinkWeight(1)));
weightMutation.getComponents().add(
0.1125,
new NEATMutateWeights(new SelectProportion(0.02),
new MutatePerturbLinkWeight(1)));
weightMutation.getComponents().add(
0.03,
new NEATMutateWeights(new SelectFixed(1),
new MutateResetLinkWeight()));
weightMutation.getComponents().add(
0.03,
new NEATMutateWeights(new SelectFixed(2),
new MutateResetLinkWeight()));
weightMutation.getComponents().add(
0.03,
new NEATMutateWeights(new SelectFixed(3),
new MutateResetLinkWeight()));
weightMutation.getComponents().add(
0.01,
new NEATMutateWeights(new SelectProportion(0.02),
new MutateResetLinkWeight()));
weightMutation.getComponents().finalizeStructure();
result.setChampMutation(weightMutation);
result.addOperation(0.5, new NEATCrossover());
result.addOperation(0.494, weightMutation);
result.addOperation(0.0005, new NEATMutateAddNode());
result.addOperation(0.005, new NEATMutateAddLink());
result.addOperation(0.0005, new NEATMutateRemoveLink());
result.getOperators().finalizeStructure();
if (population.isHyperNEAT()) {
result.setCODEC(new HyperNEATCODEC());
} else {
result.setCODEC(new NEATCODEC());
}
return result;
}
}