/* * Artificial Intelligence for Humans * Volume 2: Nature Inspired Algorithms * Java Version * http://www.aifh.org * http://www.jeffheaton.com * * Code repository: * https://github.com/jeffheaton/aifh * * Copyright 2014 by Jeff Heaton * * 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 com.heatonresearch.aifh.evolutionary.population; import com.heatonresearch.aifh.evolutionary.genome.Genome; import com.heatonresearch.aifh.evolutionary.genome.GenomeFactory; import com.heatonresearch.aifh.evolutionary.species.BasicSpecies; import com.heatonresearch.aifh.evolutionary.species.Species; import java.io.Serializable; import java.util.ArrayList; import java.util.List; /** * Defines the basic functionality for a population of genomes. The population * is made up of species. These species contain the individiual genomes that * make up the population. If you do not want to use species, then create one * species that holds every genome. */ public class BasicPopulation implements Population, Serializable { /** * The serial id. */ private static final long serialVersionUID = 1L; /** * The object name. */ private String name; /** * The species that make up the population. */ private final List<Species> species = new ArrayList<Species>(); /** * The best genome. */ private Genome bestGenome; /** * A factory that can be used to store create genomes. */ private GenomeFactory genomeFactory; /** * How many genomes should be created. */ private int populationSize; /** * Construct an empty population. */ public BasicPopulation() { this.populationSize = 0; } /** * Construct a population. * * @param thePopulationSize The population size. */ public BasicPopulation(final int thePopulationSize, final GenomeFactory theGenomeFactory) { this.populationSize = thePopulationSize; this.genomeFactory = theGenomeFactory; } /** * {@inheritDoc} */ @Override public void clear() { this.species.clear(); } /** * {@inheritDoc} */ @Override public Species createSpecies() { final Species species = new BasicSpecies(); species.setPopulation(this); getSpecies().add(species); return species; } /** * {@inheritDoc} */ @Override public Species determineBestSpecies() { for (final Species species : this.species) { if (species.getMembers().contains(this.bestGenome)) { return species; } } return null; } /** * {@inheritDoc} */ @Override public List<Genome> flatten() { final List<Genome> result = new ArrayList<Genome>(); for (final Species species : this.species) { result.addAll(species.getMembers()); } return result; } /** * {@inheritDoc} */ @Override public Genome getBestGenome() { return this.bestGenome; } /** * {@inheritDoc} */ @Override public GenomeFactory getGenomeFactory() { return this.genomeFactory; } /** * {@inheritDoc} */ @Override public int getMaxIndividualSize() { return Integer.MAX_VALUE; } /** * @return The name. */ public String getName() { return this.name; } /** * {@inheritDoc} */ @Override public int getPopulationSize() { return this.populationSize; } /** * {@inheritDoc} */ @Override public List<Species> getSpecies() { return this.species; } /** * {@inheritDoc} */ @Override public void setBestGenome(final Genome genome) { this.bestGenome = genome; } /** * {@inheritDoc} */ @Override public void setGenomeFactory(final GenomeFactory factory) { this.genomeFactory = factory; } /** * Set the name. * * @param theName The new name. */ public void setName(final String theName) { this.name = theName; } /** * {@inheritDoc} */ @Override public void setPopulationSize(final int thePopulationSize) { this.populationSize = thePopulationSize; } /** * {@inheritDoc} */ @Override public int size() { return flatten().size(); } /** * Not supported, a population cannot be fit by methods that use getLongTermMemory. * The population is made up of many elements. * * @return Nothing. */ @Override public double[] getLongTermMemory() { throw new UnsupportedOperationException(); } /** * Purge any invalid genomes. */ public void purgeInvalidGenomes() { // remove any invalid genomes int speciesNum = 0; while (speciesNum < getSpecies().size()) { Species species = getSpecies().get(speciesNum); int genomeNum = 0; while (genomeNum < species.getMembers().size()) { Genome genome = species.getMembers().get(genomeNum); if (Double.isInfinite(genome.getScore()) || Double.isInfinite(genome.getAdjustedScore()) || Double.isNaN(genome.getScore()) || Double.isNaN(genome.getAdjustedScore())) { species.getMembers().remove(genome); } else { genomeNum++; } } // is the species now empty? if (species.getMembers().size() == 0) { getSpecies().remove(species); } else { // new leader needed? if (!species.getMembers().contains(species.getLeader())) { species.setLeader(species.getMembers().get(0)); species.setBestScore(species.getLeader().getScore()); } // onto the next one! speciesNum++; } } } }