/*
* BioJava development code This code may be freely distributed and modified
* under the terms of the GNU Lesser General Public Licence. This should be
* distributed with the code. If you do not have a copy, see:
* http://www.gnu.org/copyleft/lesser.html Copyright for this code is held
* jointly by the individual authors. These should be listed in @author doc
* comments. For more information on the BioJava project and its aims, or to
* join the biojava-l mailing list, visit the home page at:
* http://www.biojava.org/
*/
package org.biojavax.ga.impl;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import org.biojava.bio.BioError;
import org.biojava.bio.symbol.IllegalAlphabetException;
import org.biojava.bio.symbol.IllegalSymbolException;
import org.biojava.utils.ChangeVetoException;
import org.biojavax.ga.GAStoppingCriteria;
import org.biojavax.ga.Organism;
import org.biojavax.ga.Population;
import org.biojavax.ga.functions.CrossOverFunction;
import org.biojavax.ga.functions.MutationFunction;
import org.biojavax.ga.functions.SelectionFunction;
/**
* A simple implementation of the GeneticAlgorithm
interface it
* is not intended that this class be overidden, hence it is final. It is much
* better to overide AbstractGeneticAlgorithm
.
*
* @author Mark Schreiber
* @author Susanne Merz
* @author Andreas Dräger
* @version 1.1
* @since 1.5
*/
public final class SimpleGeneticAlgorithm extends AbstractGeneticAlgorithm {
private int generation = 0;
private LinkedList crossResults;
public SimpleGeneticAlgorithm() {
crossResults = new LinkedList();
}
public SimpleGeneticAlgorithm(Population pop, MutationFunction mutFunc,
CrossOverFunction xFunc, SelectionFunction selFunc) {
crossResults = new LinkedList();
try {
setPopulation(pop);
setCrossOverFunction(xFunc);
setMutationFunction(mutFunc);
setSelectionFunction(selFunc);
} catch (ChangeVetoException ex) {
// can't veto changes on an unconstructed object
}
}
/**
* The current generation
*
* @return an int giving the generation number
*/
public int getGeneration() {
return generation;
}
/**
* Get a List containing details of all the cross over events during the run.
* If run(GAStoppingCriteria stoppingCriteria) has not yet been called
* the list will be empty
.
* This implementation only stores a buffer of the last 100 crosses for memory
* reasons.
*
* @return a List
of GACrossResult objects.
*/
public List getCrossResults() {
return crossResults;
}
public synchronized void run(GAStoppingCriteria stoppingCriteria)
throws ChangeVetoException, IllegalAlphabetException,
IllegalSymbolException {
while (stoppingCriteria.stop(this) != true) {
// select the fit for reproduction
getSelectionFunction().select(getPopulation(), this);
// cross pairs of individuals
Set partners = getPopulation().getOrganisms();
for (Iterator it = partners.iterator(); it.hasNext();) {
Organism a = (Organism) it.next();
if (it.hasNext()) {
Organism b = (Organism) it.next();
try {
for (int i = 0; i < a.getChromosomes().length
&& i < b.getChromosomes().length; i++) {
crossResults.addLast(getCrossOverFunction().performCrossOver(
a.getChromosomes()[i], b.getChromosomes()[i]));
while (crossResults.size() > 100) {
crossResults.removeFirst();
}
}
} catch (ChangeVetoException ex) {
// shouldn't happen as long as sensible implementations of
// SymbolList
// are used.
throw new BioError("Unmodifiable chromosome", ex);
}
} else {
break;
}
}
// mutate
for (Iterator it = getPopulation().organisms(); it.hasNext();) {
Organism o = (Organism) it.next();
for (int i = 0; i < o.getChromosomes().length; i++) {
getMutationFunction().mutate(o.getChromosomes()[i]);
}
o.setFitness(getFitnessFunction().fitness(o, population, this));
}
generation++;
}
}
}