/*
* 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.genome;
import java.util.ArrayList;
import java.util.List;
import org.encog.persist.annotations.EGAttribute;
import org.encog.persist.annotations.EGIgnore;
import org.encog.solve.genetic.GeneticAlgorithm;
import org.encog.solve.genetic.GeneticError;
/**
* A basic abstract genome. Provides base functionality.
*/
public abstract class BasicGenome implements Genome {
/**
* The adjusted score.
*/
@EGAttribute
private double adjustedScore;
/**
* The amount to spawn.
*/
@EGAttribute
private double amountToSpawn;
/**
* The chromosomes for this gene.
*/
private final List<Chromosome> chromosomes = new ArrayList<Chromosome>();
/**
* The genetic algorithm for this gene.
*/
@EGIgnore
private GeneticAlgorithm geneticAlgorithm;
/**
* The genome id.
*/
@EGAttribute
private long genomeID;
/**
* The organism generated by this gene.
*/
@EGIgnore
private Object organism;
/**
* The score of this genome.
*/
@EGAttribute
private double score = 0;
/**
* Construct a basic genome.
* @param geneticAlgorithm
*/
public BasicGenome(final GeneticAlgorithm geneticAlgorithm) {
this.geneticAlgorithm = geneticAlgorithm;
}
/**
* @return The number of genes in this genome.
*/
public int calculateGeneCount() {
int result = 0;
// sum the genes in the chromosomes.
for (final Chromosome chromosome : this.chromosomes) {
result += chromosome.getGenes().size();
}
return result;
}
/**
* {@inheritDoc}
*/
public 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.
*/
public double getAdjustedScore() {
return this.adjustedScore;
}
/**
* @return The amount this genome will spawn.
*/
public double getAmountToSpawn() {
return this.amountToSpawn;
}
/**
* @return The number of chromosomes.
*/
public List<Chromosome> getChromosomes() {
return this.chromosomes;
}
/**
* @return The genetic algorithm.
*/
public GeneticAlgorithm getGeneticAlgorithm() {
return this.geneticAlgorithm;
}
/**
* @return The genome id.
*/
public long getGenomeID() {
return this.genomeID;
}
/**
* @return The organism produced.
*/
public Object getOrganism() {
return this.organism;
}
/**
* @return The score.
*/
public 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.
*/
public 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 adjustedScore
* The score.
*/
public void setAdjustedScore(final double adjustedScore) {
this.adjustedScore = adjustedScore;
}
/**
* Set the amount to spawn.
*
* @param amountToSpawn
* The amount to spawn.
*/
public void setAmountToSpawn(final double amountToSpawn) {
this.amountToSpawn = amountToSpawn;
}
/**
* Set the genetic algorithm to use.
* @param ga The genetic algorithm to use.
*/
public void setGeneticAlgorithm(final GeneticAlgorithm ga) {
this.geneticAlgorithm = ga;
}
/**
* Set the genome id.
*
* @param genomeID
* the genome id.
*/
public void setGenomeID(final long genomeID) {
this.genomeID = genomeID;
}
/**
* Set the organism.
*
* @param organism
* The organism.
*/
public void setOrganism(final Object organism) {
this.organism = organism;
}
/**
* Set the score.
*
* @param score
* Set the score.
*/
public void setScore(final double score) {
this.score = score;
}
/**
* {@inheritDoc}
*/
@Override
public String toString() {
final StringBuilder builder = new StringBuilder();
builder.append("[BasicGenome: score=");
builder.append(getScore());
return builder.toString();
}
}