/*
* Encog(tm) Core v3.0 - Java Version
* http://www.heatonresearch.com/encog/
* http://code.google.com/p/encog-java/
* Copyright 2008-2011 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.genetic.genome;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import org.encog.ml.genetic.GeneticAlgorithm;
import org.encog.ml.genetic.GeneticError;
import org.encog.ml.genetic.population.Population;
/**
* A basic abstract genome. Provides base functionality.
*/
public abstract class BasicGenome implements Genome, Serializable {
/**
* Serial id.
*/
private static final long serialVersionUID = 1L;
/**
* The adjusted score.
*/
private double adjustedScore;
/**
* The amount to spawn.
*/
private double amountToSpawn;
/**
* The chromosomes for this gene.
*/
private final List<Chromosome> chromosomes = new ArrayList<Chromosome>();
/**
* The genetic algorithm for this gene.
*/
private transient GeneticAlgorithm geneticAlgorithm;
/**
* The genome id.
*/
private long genomeID;
/**
* The organism generated by this gene.
*/
private transient Object organism;
/**
* The score of this genome.
*/
private double score = 0;
/**
* The population this genome belongs to.
*/
private Population population;
/**
* @return The number of genes in this genome.
*/
@Override
public final int calculateGeneCount() {
int result = 0;
// sum the genes in the chromosomes.
for (final Chromosome chromosome : this.chromosomes) {
result += chromosome.getGenes().size();
}
return result;
}
/**
* {@inheritDoc}
*/
@Override
public final int compareTo(final Genome other) {
if (this.geneticAlgorithm.getCalculateScore().shouldMinimize()) {
if (getScore() > other.getScore()) {
return 1;
}
return -1;
} else {
if (getScore() > other.getScore()) {
return -1;
}
return 1;
}
}
/**
* @return The adjusted score, which considers bonuses.
*/
@Override
public final double getAdjustedScore() {
return this.adjustedScore;
}
/**
* @return The amount this genome will spawn.
*/
@Override
public final double getAmountToSpawn() {
return this.amountToSpawn;
}
/**
* @return The number of chromosomes.
*/
@Override
public final List<Chromosome> getChromosomes() {
return this.chromosomes;
}
/**
* @return The genetic algorithm.
*/
@Override
public final GeneticAlgorithm getGeneticAlgorithm() {
return this.geneticAlgorithm;
}
/**
* @return The genome id.
*/
@Override
public final long getGenomeID() {
return this.genomeID;
}
/**
* @return The organism produced.
*/
@Override
public final Object getOrganism() {
return this.organism;
}
/**
* @return the population
*/
@Override
public final Population getPopulation() {
return this.population;
}
/**
* @return The score.
*/
@Override
public final double getScore() {
return this.score;
}
/**
* Mate two genomes. Will loop over all chromosomes.
*
* @param father
* The father.
* @param child1
* The first child.
* @param child2
* The second child.
*/
@Override
public final void mate(final Genome father, final Genome child1,
final Genome child2) {
final int motherChromosomes = getChromosomes().size();
final int fatherChromosomes = father.getChromosomes().size();
if (motherChromosomes != fatherChromosomes) {
throw new GeneticError(
"Mother and father must have same chromosome count, Mother:"
+ motherChromosomes + ",Father:"
+ fatherChromosomes);
}
for (int i = 0; i < fatherChromosomes; i++) {
final Chromosome motherChromosome = this.chromosomes.get(i);
final Chromosome fatherChromosome = father.getChromosomes().get(i);
final Chromosome offspring1Chromosome = child1.getChromosomes()
.get(i);
final Chromosome offspring2Chromosome = child2.getChromosomes()
.get(i);
this.geneticAlgorithm.getCrossover().mate(motherChromosome,
fatherChromosome, offspring1Chromosome,
offspring2Chromosome);
if (Math.random() < this.geneticAlgorithm.getMutationPercent()) {
this.geneticAlgorithm.getMutate().performMutation(
offspring1Chromosome);
}
if (Math.random() < this.geneticAlgorithm.getMutationPercent()) {
this.geneticAlgorithm.getMutate().performMutation(
offspring2Chromosome);
}
}
child1.decode();
child2.decode();
this.geneticAlgorithm.calculateScore(child1);
this.geneticAlgorithm.calculateScore(child2);
}
/**
* Set the adjusted score.
*
* @param theAdjustedScore
* The score.
*/
@Override
public final void setAdjustedScore(final double theAdjustedScore) {
this.adjustedScore = theAdjustedScore;
}
/**
* Set the amount to spawn.
*
* @param theAmountToSpawn
* The amount to spawn.
*/
@Override
public final void setAmountToSpawn(final double theAmountToSpawn) {
this.amountToSpawn = theAmountToSpawn;
}
/**
* Set the genetic algorithm to use.
*
* @param ga
* The genetic algorithm to use.
*/
@Override
public final void setGeneticAlgorithm(final GeneticAlgorithm ga) {
this.geneticAlgorithm = ga;
}
/**
* Set the genome id.
*
* @param theGenomeID
* the genome id.
*/
@Override
public final void setGenomeID(final long theGenomeID) {
this.genomeID = theGenomeID;
}
/**
* Set the organism.
*
* @param theOrganism
* The organism.
*/
public final void setOrganism(final Object theOrganism) {
this.organism = theOrganism;
}
/**
* @param thePopulation
* the population to set
*/
@Override
public final void setPopulation(final Population thePopulation) {
this.population = thePopulation;
}
/**
* Set the score.
*
* @param theScore
* Set the score.
*/
@Override
public final void setScore(final double theScore) {
this.score = theScore;
}
/**
* {@inheritDoc}
*/
@Override
public final String toString() {
final StringBuilder builder = new StringBuilder();
builder.append("[");
builder.append(this.getClass().getSimpleName());
builder.append(": score=");
builder.append(getScore());
return builder.toString();
}
}