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.functions;
013
014import java.util.Iterator;
015
016import org.biojava.bio.BioError;
017import org.biojava.utils.ChangeVetoException;
018import org.biojavax.ga.GeneticAlgorithm;
019import org.biojavax.ga.Organism;
020import org.biojavax.ga.Population;
021import org.biojavax.ga.exception.IllegalOrganismException;
022import org.biojavax.ga.util.WeightedSet;
023
024/**
025 * <p>
026 * A Selection function that determines the proportion of individuals in a new
027 * population proportionally to their fitness. The population size is not
028 * allowed to grow. Individuals are randomly selected for replication, those
029 * with greater fitness tend to replicate more often.
030 *
031 * @author Mark Schreiber
032 * @author Susanne Merz
033 * @author Andreas Dr&auml;ger
034 * @version 1.1
035 */
036
037public class ProportionalSelection implements SelectionFunction {
038
039        public ProportionalSelection() {
040
041        }
042
043        public Population select(Population pop, GeneticAlgorithm genAlg)
044            throws ChangeVetoException {
045                WeightedSet set = new WeightedSet();
046                int size = pop.size();
047
048                for (Iterator i = pop.organisms(); i.hasNext();) {
049                        Object item = i.next();
050                        double fit[] = ((Organism) item).getFitness();
051                        // TODO: maybe we have to consider every fitness value.
052                        set.setWeight(item, fit[0]);
053                }
054
055                pop.removeAllOrganisms();
056
057                for (int i = 0; i < size; i++) {
058                        try {
059                                Organism o = (Organism) set.sample();
060                                String name = o.getName().split(":")[0];
061
062                                // to begin with the name may not have a ":" in it
063                                if (name.equals("")) {
064                                        name = o.getName();
065                                }
066
067                                // System.out.println("name: "+name);
068                                o = o.replicate(name + ":" + i);
069                                pop.addOrganism(o);
070                        } catch (IllegalOrganismException ex) {
071                                throw new BioError("A previously legal organism is now illegal??", ex);
072                        }
073                }
074
075                return pop;
076        }
077}