/* * Encog(tm) Core v2.5 - Java Version * http://www.heatonresearch.com/encog/ * http://code.google.com/p/encog-java/ * Copyright 2008-2010 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.networks.training.neat; import org.encog.neural.networks.synapse.neat.NEATNeuronType; import org.encog.persist.annotations.EGReference; import org.encog.solve.genetic.genes.Gene; import org.encog.solve.genetic.genome.Chromosome; import org.encog.solve.genetic.innovation.BasicInnovationList; import org.encog.solve.genetic.innovation.Innovation; import org.encog.solve.genetic.population.Population; /** * Implements a NEAT innovation list. * * NeuroEvolution of Augmenting Topologies (NEAT) is a genetic algorithm for the * generation of evolving artificial neural networks. It was developed by Ken * Stanley while at The University of Texas at Austin. * * http://www.cs.ucf.edu/~kstanley/ * */ public class NEATInnovationList extends BasicInnovationList { /** * The next neuron id. */ private long nextNeuronID = 0; /** * The population. */ @EGReference private Population population; /** * The default constructor, used mainly for persistance. */ public NEATInnovationList() { } /** * Construct an innovation list. * * @param population * The population. * @param links * The links. * @param neurons * THe neurons. */ public NEATInnovationList(final Population population, final Chromosome links, final Chromosome neurons) { this.population = population; for (final Gene gene : neurons.getGenes()) { final NEATNeuronGene neuronGene = (NEATNeuronGene) gene; final NEATInnovation innovation = new NEATInnovation(neuronGene, population.assignInnovationID(), assignNeuronID()); add(innovation); } for (final Gene gene : links.getGenes()) { final NEATLinkGene linkGene = (NEATLinkGene) gene; final NEATInnovation innovation = new NEATInnovation(linkGene .getFromNeuronID(), linkGene.getToNeuronID(), NEATInnovationType.NewLink, this.population .assignInnovationID()); add(innovation); } } /** * Assign a neuron ID. * * @return The neuron id. */ private long assignNeuronID() { return this.nextNeuronID++; } /** * Check to see if we already have an innovation. * * @param in * The input neuron. * @param out * THe output neuron. * @param type * The type. * @return The innovation, either new or existing if found. */ public NEATInnovation checkInnovation(final long in, final long out, final NEATInnovationType type) { for (final Innovation i : getInnovations()) { final NEATInnovation innovation = (NEATInnovation) i; if ((innovation.getFromNeuronID() == in) && (innovation.getToNeuronID() == out) && (innovation.getInnovationType() == type)) { return innovation; } } return null; } /** * Create a new neuron gene from an id. * * @param neuronID * The neuron id. * @return The neuron gene. */ public NEATNeuronGene createNeuronFromID(final long neuronID) { final NEATNeuronGene result = new NEATNeuronGene(NEATNeuronType.Hidden, 0, 0, 0); for (final Innovation i : getInnovations()) { final NEATInnovation innovation = (NEATInnovation) i; if (innovation.getNeuronID() == neuronID) { result.setNeuronType(innovation.getNeuronType()); result.setId(innovation.getNeuronID()); result.setSplitY(innovation.getSplitY()); result.setSplitX(innovation.getSplitX()); return result; } } return result; } /** * Create a new innovation. * * @param in * The input neuron. * @param out * The output neuron. * @param type * The type. */ public void createNewInnovation(final long in, final long out, final NEATInnovationType type) { final NEATInnovation newInnovation = new NEATInnovation(in, out, type, this.population.assignInnovationID()); if (type == NEATInnovationType.NewNeuron) { newInnovation.setNeuronID(assignNeuronID()); } add(newInnovation); } /** * Create a new innovation. * * @param from * The from neuron. * @param to * The to neuron. * @param innovationType * THe innovation type. * @param neuronType * The neuron type. * @param x * The x-coordinate. * @param y * The y-coordinate. * @return The new innovation. */ public long createNewInnovation(final long from, final long to, final NEATInnovationType innovationType, final NEATNeuronType neuronType, final double x, final double y) { final NEATInnovation newInnovation = new NEATInnovation(from, to, innovationType, this.population.assignInnovationID(), neuronType, x, y); if (innovationType == NEATInnovationType.NewNeuron) { newInnovation.setNeuronID(assignNeuronID()); } add(newInnovation); return (this.nextNeuronID - 1); // ??????? should it be innov? } }