/* * Encog(tm) Core v3.4 - Java Version * http://www.heatonresearch.com/encog/ * https://github.com/encog/encog-java-core * Copyright 2008-2016 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 java.io.Serializable; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import org.encog.engine.network.activation.ActivationFunction; import org.encog.ml.MLMethod; import org.encog.ml.ea.codec.GeneticCODEC; import org.encog.ml.ea.genome.Genome; import org.encog.ml.genetic.GeneticError; import org.encog.neural.NeuralNetworkError; import org.encog.neural.neat.training.NEATGenome; import org.encog.neural.neat.training.NEATLinkGene; import org.encog.neural.neat.training.NEATNeuronGene; /** * This CODEC is used to create phenomes (NEATNetwork) objects using a genome * (NEATGenome). Conversion is only one direction. You are allowed to transform * a NEAT genome into a NEATNetwork, but you cannot transform a NEAT phenome * back into a genome. The main reason is I have not found a great deal of need * to go the other direction. If someone ever does find a need and creates a * encode method, please consider contributing it to the Encog project. :) * * ----------------------------------------------------------------------------- * 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 NEATCODEC implements GeneticCODEC, Serializable { /** * The serial ID. */ private static final long serialVersionUID = 1L; /** * {@inheritDoc} */ @Override public MLMethod decode(final Genome genome) { final NEATGenome neatGenome = (NEATGenome) genome; final NEATPopulation pop = (NEATPopulation) neatGenome.getPopulation(); final List<NEATNeuronGene> neuronsChromosome = neatGenome .getNeuronsChromosome(); final List<NEATLinkGene> linksChromosome = neatGenome .getLinksChromosome(); if (neuronsChromosome.get(0).getNeuronType() != NEATNeuronType.Bias) { throw new NeuralNetworkError( "The first neuron must be the bias neuron, this genome is invalid."); } final List<NEATLink> links = new ArrayList<NEATLink>(); final ActivationFunction[] afs = new ActivationFunction[neuronsChromosome .size()]; for (int i = 0; i < afs.length; i++) { afs[i] = neuronsChromosome.get(i).getActivationFunction(); } final Map<Long, Integer> lookup = new HashMap<Long, Integer>(); for (int i = 0; i < neuronsChromosome.size(); i++) { final NEATNeuronGene neuronGene = neuronsChromosome.get(i); lookup.put(neuronGene.getId(), i); } // loop over connections for (int i = 0; i < linksChromosome.size(); i++) { final NEATLinkGene linkGene = linksChromosome.get(i); if (linkGene.isEnabled()) { links.add(new NEATLink(lookup.get(linkGene.getFromNeuronID()), lookup.get(linkGene.getToNeuronID()), linkGene .getWeight())); } } Collections.sort(links); final NEATNetwork network = new NEATNetwork(neatGenome.getInputCount(), neatGenome.getOutputCount(), links, afs); network.setActivationCycles(pop.getActivationCycles()); return network; } /** * This method is not currently implemented. If you have need of it, and do * implement a conversion from a NEAT phenotype to a genome, consider * contribution to the Encog project. * @param phenotype Not used. * @return Not used. */ @Override public Genome encode(final MLMethod phenotype) { throw new GeneticError( "Encoding of a NEAT network is not supported."); } }