/* * 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.solve.genetic; import org.encog.engine.concurrency.EngineConcurrency; import org.encog.engine.concurrency.TaskGroup; import org.encog.neural.networks.ContextClearable; import org.encog.solve.genetic.crossover.Crossover; import org.encog.solve.genetic.genome.CalculateGenomeScore; import org.encog.solve.genetic.genome.Genome; import org.encog.solve.genetic.genome.GenomeComparator; import org.encog.solve.genetic.mutate.Mutate; import org.encog.solve.genetic.population.Population; import org.encog.solve.genetic.species.Species; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Implements a genetic algorithm. This is an abstract class. Other classes are * provided by Encog use this base class to train neural networks or * provide an answer to the traveling salesman problem. * * The genetic algorithm is also capable of using a thread pool to speed * execution. */ public class GeneticAlgorithm { /** * The score calculation object. */ private CalculateGenomeScore calculateScore; /** * The genome comparator. */ private GenomeComparator comparator; /** * The crossover object. */ private Crossover crossover; /** * The logging object. */ @SuppressWarnings("unused") private final Logger logger = LoggerFactory.getLogger(this.getClass()); /** * Percent of the population that the mating population chooses partners. * from. */ private double matingPopulation; /** * The mutation object to use. */ private Mutate mutate; /** * The percent that should mutate. */ private double mutationPercent; /** * What percent should be chosen to mate. They will choose partners from the * entire mating population. */ private double percentToMate; /** * The population. */ private Population population; /** * Calculate the score for this genome. The genome's score will be set. * @param g The genome to calculate for. */ public void calculateScore(final Genome g) { if( g.getOrganism() instanceof ContextClearable ) ((ContextClearable)g.getOrganism()).clearContext(); final double score = calculateScore.calculateScore(g); g.setScore(score); } /** * @return The score calculation object. */ public CalculateGenomeScore getCalculateScore() { return calculateScore; } /** * @return The comparator. */ public GenomeComparator getComparator() { return comparator; } /** * @return The crossover object. */ public Crossover getCrossover() { return crossover; } /** * Get the mating population. * * @return The mating population percent. */ public double getMatingPopulation() { return matingPopulation; } /** * @return The mutate object. */ public Mutate getMutate() { return mutate; } /** * Get the mutation percent. * * @return The mutation percent. */ public double getMutationPercent() { return mutationPercent; } /** * Get the percent to mate. * * @return The percent to mate. */ public double getPercentToMate() { return percentToMate; } /** * @return The population. */ public Population getPopulation() { return population; } /** * Modify the weight matrix and bias values based on the last call to * calcError. * * @throws NeuralNetworkException */ public void iteration() { final int countToMate = (int) (population.getPopulationSize() * getPercentToMate()); final int offspringCount = countToMate * 2; int offspringIndex = population.getPopulationSize() - offspringCount; final int matingPopulationSize = (int) (population.getPopulationSize() * getMatingPopulation()); final TaskGroup group = EngineConcurrency.getInstance() .createTaskGroup(); // mate and form the next generation for (int i = 0; i < countToMate; i++) { final Genome mother = population.getGenomes().get(i); final int fatherInt = (int) (Math.random() * matingPopulationSize); final Genome father = population.getGenomes().get(fatherInt); final Genome child1 = population.getGenomes().get(offspringIndex); final Genome child2 = population.getGenomes().get( offspringIndex + 1); final MateWorker worker = new MateWorker(mother, father, child1, child2); EngineConcurrency.getInstance().processTask(worker, group); offspringIndex += 2; } group.waitForComplete(); // sort the next generation population.sort(); } /** * Set the score calculation object. * @param calculateScore The score calculation object. */ public void setCalculateScore(final CalculateGenomeScore calculateScore) { this.calculateScore = calculateScore; } /** * Set the comparator. * @param comparator The comparator. */ public void setComparator(final GenomeComparator comparator) { this.comparator = comparator; } /** * Set the crossover object. * @param crossover The crossover object. */ public void setCrossover(final Crossover crossover) { this.crossover = crossover; } /** * Set the mating population percent. * * @param matingPopulation * The mating population percent. */ public void setMatingPopulation(final double matingPopulation) { this.matingPopulation = matingPopulation; } /** * Set the mutate object. * @param mutate The mutate object. */ public void setMutate(final Mutate mutate) { this.mutate = mutate; } /** * Set the mutation percent. * * @param mutationPercent * The percent to mutate. */ public void setMutationPercent(final double mutationPercent) { this.mutationPercent = mutationPercent; } /** * Set the percent to mate. * * @param percentToMate * The percent to mate. */ public void setPercentToMate(final double percentToMate) { this.percentToMate = percentToMate; } /** * Set the population. * @param population The population. */ public void setPopulation(final Population population) { this.population = population; } /** * Add a genome. * @param species The species to add. * @param genome The genome to add. */ public void addSpeciesMember(final Species species, final Genome genome) { if (this.getComparator().isBetterThan(genome.getScore(), species.getBestScore())) { species.setBestScore( genome.getScore() ); species.setGensNoImprovement(0); species.setLeader(genome); } species.getMembers().add(genome); } }