001/* 002 * BioJava development code This code may be freely distributed and modified 003 * under the terms of the GNU Lesser General Public Licence. This should be 004 * distributed with the code. If you do not have a copy, see: 005 * http://www.gnu.org/copyleft/lesser.html Copyright for this code is held 006 * jointly by the individual authors. These should be listed in @author doc 007 * comments. For more information on the BioJava project and its aims, or to 008 * join the biojava-l mailing list, visit the home page at: 009 * http://www.biojava.org/ 010 */ 011 012package org.biojavax.ga.impl; 013 014import java.util.Iterator; 015import java.util.LinkedList; 016import java.util.List; 017import java.util.Set; 018 019import org.biojava.bio.BioError; 020import org.biojava.bio.symbol.IllegalAlphabetException; 021import org.biojava.bio.symbol.IllegalSymbolException; 022import org.biojava.utils.ChangeVetoException; 023import org.biojavax.ga.GAStoppingCriteria; 024import org.biojavax.ga.Organism; 025import org.biojavax.ga.Population; 026import org.biojavax.ga.functions.CrossOverFunction; 027import org.biojavax.ga.functions.MutationFunction; 028import org.biojavax.ga.functions.SelectionFunction; 029 030/** 031 * A simple implementation of the <code>GeneticAlgorithm</code> interface it 032 * is not intended that this class be overidden, hence it is final. It is much 033 * better to overide <code>AbstractGeneticAlgorithm</code>. 034 * 035 * @author Mark Schreiber 036 * @author Susanne Merz 037 * @author Andreas Dräger 038 * @version 1.1 039 * @since 1.5 040 */ 041 042public final class SimpleGeneticAlgorithm extends AbstractGeneticAlgorithm { 043 private int generation = 0; 044 045 private LinkedList crossResults; 046 047 public SimpleGeneticAlgorithm() { 048 crossResults = new LinkedList(); 049 } 050 051 public SimpleGeneticAlgorithm(Population pop, MutationFunction mutFunc, 052 CrossOverFunction xFunc, SelectionFunction selFunc) { 053 crossResults = new LinkedList(); 054 try { 055 setPopulation(pop); 056 setCrossOverFunction(xFunc); 057 setMutationFunction(mutFunc); 058 setSelectionFunction(selFunc); 059 } catch (ChangeVetoException ex) { 060 // can't veto changes on an unconstructed object 061 } 062 } 063 064 /** 065 * The current generation 066 * 067 * @return an int giving the generation number 068 */ 069 public int getGeneration() { 070 return generation; 071 } 072 073 /** 074 * Get a List containing details of all the cross over events during the run. 075 * If <code>run(GAStoppingCriteria stoppingCriteria) has not yet been called 076 * the list will be empty</code>. 077 * This implementation only stores a buffer of the last 100 crosses for memory 078 * reasons. 079 * 080 * @return a <code>List</code> of GACrossResult objects. 081 */ 082 public List getCrossResults() { 083 return crossResults; 084 } 085 086 public synchronized void run(GAStoppingCriteria stoppingCriteria) 087 throws ChangeVetoException, IllegalAlphabetException, 088 IllegalSymbolException { 089 while (stoppingCriteria.stop(this) != true) { 090 // select the fit for reproduction 091 getSelectionFunction().select(getPopulation(), this); 092 093 // cross pairs of individuals 094 Set partners = getPopulation().getOrganisms(); 095 for (Iterator it = partners.iterator(); it.hasNext();) { 096 Organism a = (Organism) it.next(); 097 if (it.hasNext()) { 098 Organism b = (Organism) it.next(); 099 100 try { 101 for (int i = 0; i < a.getChromosomes().length 102 && i < b.getChromosomes().length; i++) { 103 104 crossResults.addLast(getCrossOverFunction().performCrossOver( 105 a.getChromosomes()[i], b.getChromosomes()[i])); 106 107 while (crossResults.size() > 100) { 108 crossResults.removeFirst(); 109 } 110 } 111 } catch (ChangeVetoException ex) { 112 // shouldn't happen as long as sensible implementations of 113 // SymbolList 114 // are used. 115 throw new BioError("Unmodifiable chromosome", ex); 116 } 117 } else { 118 break; 119 } 120 } 121 122 // mutate 123 for (Iterator it = getPopulation().organisms(); it.hasNext();) { 124 Organism o = (Organism) it.next(); 125 for (int i = 0; i < o.getChromosomes().length; i++) { 126 getMutationFunction().mutate(o.getChromosomes()[i]); 127 } 128 o.setFitness(getFitnessFunction().fitness(o, population, this)); 129 } 130 131 generation++; 132 } 133 } 134 135}