/*
* 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.ml.ea.population;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import org.encog.ml.BasicML;
import org.encog.ml.ea.genome.Genome;
import org.encog.ml.ea.genome.GenomeFactory;
import org.encog.ml.ea.rules.BasicRuleHolder;
import org.encog.ml.ea.rules.RuleHolder;
import org.encog.ml.ea.species.BasicSpecies;
import org.encog.ml.ea.species.Species;
/**
* 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 extends BasicML 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;
}
/**
* Holds rewrite and constraint rules.
*/
private RuleHolder rules = new BasicRuleHolder();
/**
* Construct a population.
*
* @param thePopulationSize
* The population size.
* @param theGenomeFactory factory that can be used to store create genomes.
*/
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();
}
/**
* {@inheritDoc}
*/
@Override
public void updateProperties() {
}
/**
* @return the rules
*/
@Override
public RuleHolder getRules() {
return this.rules;
}
/**
* @param rules
* the rules to set
*/
@Override
public void setRules(final RuleHolder rules) {
this.rules = rules;
}
/**
* 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++;
}
}
}
}