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; 015 016import org.biojava.utils.AbstractChangeable; 017import org.biojava.utils.ChangeEvent; 018import org.biojava.utils.ChangeSupport; 019import org.biojava.utils.ChangeVetoException; 020import org.biojavax.ga.GeneticAlgorithm; 021import org.biojavax.ga.Organism; 022import org.biojavax.ga.Population; 023import org.biojavax.ga.functions.CrossOverFunction; 024import org.biojavax.ga.functions.FitnessFunction; 025import org.biojavax.ga.functions.MutationFunction; 026import org.biojavax.ga.functions.SelectionFunction; 027 028/** 029 * Base class from which most implementations of GeneticAlgorithm will inherit. 030 * 031 * @author Mark Schreiber 032 * @author Susanne Merz 033 * @author Andreas Dräger 034 * @version 1.1 035 * @since 1.5 036 */ 037 038public abstract class AbstractGeneticAlgorithm extends AbstractChangeable 039 implements GeneticAlgorithm { 040 041 protected Population population; 042 043 private CrossOverFunction crossF; 044 045 private SelectionFunction selectF; 046 047 private MutationFunction mutF; 048 049 private FitnessFunction fit; 050 051 protected AbstractGeneticAlgorithm() { 052 population = new SimplePopulation(); 053 } 054 055 public final CrossOverFunction getCrossOverFunction() { 056 return crossF; 057 } 058 059 /* 060 * (non-Javadoc) 061 * 062 * @see org.biojavax.ga.GeneticAlgorithm#getFitnessFunction() 063 */ 064 public FitnessFunction getFitnessFunction() { 065 return fit; 066 } 067 068 public final MutationFunction getMutationFunction() { 069 return mutF; 070 } 071 072 public final Population getPopulation() { 073 return population; 074 } 075 076 public final SelectionFunction getSelectionFunction() { 077 return selectF; 078 } 079 080 /** 081 * Assigns a fitness value to each organism within the population according to 082 * the currently set fitness function. If no population or no fitness function 083 * is set, nothing will happen. 084 */ 085 public void initPopulation() { 086 if ((population != null) && (fit != null)) 087 for (Iterator i = population.getOrganisms().iterator(); i.hasNext();) { 088 Organism o = (Organism) i.next(); 089 o.setFitness(fit.fitness(o, population, this)); 090 } 091 } 092 093 public final void setCrossOverFunction(CrossOverFunction function) 094 throws ChangeVetoException { 095 if (!hasListeners()) { 096 this.crossF = function; 097 } else { 098 ChangeEvent ce = new ChangeEvent(this, GeneticAlgorithm.POPULATION, 099 function, this.crossF); 100 ChangeSupport changeSupport = super 101 .getChangeSupport(GeneticAlgorithm.POPULATION); 102 synchronized (changeSupport) { 103 changeSupport.firePreChangeEvent(ce); 104 this.crossF = function; 105 changeSupport.firePostChangeEvent(ce); 106 } 107 } 108 } 109 110 /* 111 * (non-Javadoc) 112 * 113 * @see org.biojavax.ga.GeneticAlgorithm#setFitnessFunction(org.biojavax.ga.functions.FitnessFunction) 114 */ 115 public final void setFitnessFunction(FitnessFunction func) 116 throws ChangeVetoException { 117 if (!hasListeners()) { 118 fit = func; 119 initPopulation(); 120 } else { 121 ChangeEvent ce = new ChangeEvent(this, GeneticAlgorithm.FITNESS_FUNCTION, 122 func, fit); 123 ChangeSupport changeSupport = super 124 .getChangeSupport(GeneticAlgorithm.FITNESS_FUNCTION); 125 synchronized (changeSupport) { 126 changeSupport.firePreChangeEvent(ce); 127 fit = func; 128 changeSupport.firePostChangeEvent(ce); 129 } 130 } 131 } 132 133 public final void setMutationFunction(MutationFunction function) 134 throws ChangeVetoException { 135 if (!hasListeners()) { 136 this.mutF = function; 137 } else { 138 ChangeEvent ce = new ChangeEvent(this, GeneticAlgorithm.POPULATION, 139 function, this.mutF); 140 ChangeSupport changeSupport = super 141 .getChangeSupport(GeneticAlgorithm.POPULATION); 142 synchronized (changeSupport) { 143 changeSupport.firePreChangeEvent(ce); 144 this.mutF = function; 145 changeSupport.firePostChangeEvent(ce); 146 } 147 } 148 } 149 150 public final void setPopulation(Population pop) throws ChangeVetoException { 151 if (!hasListeners()) { 152 population = pop; 153 initPopulation(); 154 } else { 155 ChangeEvent ce = new ChangeEvent(this, GeneticAlgorithm.POPULATION, pop, 156 this.population); 157 ChangeSupport changeSupport = super 158 .getChangeSupport(GeneticAlgorithm.POPULATION); 159 synchronized (changeSupport) { 160 changeSupport.firePreChangeEvent(ce); 161 population = pop; 162 changeSupport.firePostChangeEvent(ce); 163 } 164 } 165 } 166 167 public final void setSelectionFunction(SelectionFunction function) 168 throws ChangeVetoException { 169 if (!hasListeners()) { 170 this.selectF = function; 171 } else { 172 ChangeEvent ce = new ChangeEvent(this, GeneticAlgorithm.POPULATION, 173 function, this.selectF); 174 ChangeSupport changeSupport = super 175 .getChangeSupport(GeneticAlgorithm.POPULATION); 176 synchronized (changeSupport) { 177 changeSupport.firePreChangeEvent(ce); 178 this.selectF = function; 179 changeSupport.firePostChangeEvent(ce); 180 } 181 } 182 } 183}