001/*
002 *                    BioJava development code
003 *
004 * This code may be freely distributed and modified under the
005 * terms of the GNU Lesser General Public Licence.  This should
006 * be distributed with the code.  If you do not have a copy,
007 * see:
008 *
009 *      http://www.gnu.org/copyleft/lesser.html
010 *
011 * Copyright for this code is held jointly by the individual
012 * authors.  These should be listed in @author doc comments.
013 *
014 * For more information on the BioJava project and its aims,
015 * or to join the biojava-l mailing list, visit the home page
016 * at:
017 *
018 *      http://www.biojava.org/
019 *
020 */
021
022
023package org.biojavax.ga.functions;
024
025import org.biojava.bio.symbol.PointLocation;
026import org.biojava.bio.symbol.SymbolList;
027import org.biojava.utils.ChangeListener;
028import org.biojava.utils.ChangeType;
029import org.biojava.utils.ChangeVetoException;
030import org.biojava.utils.Changeable;
031
032
033/**
034 * Crosses two chromosomes. The basic usage of the class would be
035 * something like choosing two chromosomes that you want to cross over and setting
036 * these with the <code>setChromosomePair</code> method. Next you would call one of
037 * the <code>performCrossOver</code> methods to do the crossing and finally you
038 * would retreive the chromsome pair with the <code>getChromosomes</code> method.
039 *
040 * @author Mark Schreiber
041 * @version 1.0
042 * @since 1.5
043 */
044
045public interface CrossOverFunction extends Changeable{
046
047  /**
048   * Performs a cross between the pair of chromosomes
049   * @param chromA The first chromosome in the cross
050   * @param chromB The second chromosome in the cross
051   * @return A <code>GACross</code> that holds the results of the cross
052   * @throws ChangeVetoException if the chromosomes are unmodifiable
053   */
054  public GACrossResult performCrossOver(SymbolList chromA, SymbolList chromB)
055    throws ChangeVetoException;
056
057  /**
058   * Sets an upper limit on the number of crosses. Its up to
059   * the implementation to decide what to do when the limit is reached although
060   * a good convention would be to keep only the first N crosses from the left
061   * end (5' end) of the sequence.
062   *
063   * By convention the default upper limit is DEFAULT_MAX_CROSS (eg infinite).
064   *  This value should be used as the default by all implementations.
065   *
066   * @param maxCrossOvers the limit on crosses
067   * @throws ChangeVetoException if a ChangeListener vetoes this change
068   */
069  public void setMaxCrossOvers(int maxCrossOvers) throws ChangeVetoException;
070
071  /**
072   * @return the limit on crosses.
073   */
074  public int getMaxCrossOvers();
075
076  /**
077   * Sets the probability of crossing at each base. Each position
078   * in the array corresponds to a position in the sequences to be crossed.
079   *
080   * The probability of a cross occuring <em>after</em> position 1 in the <code>SymbolList</code>
081   * is given by <code>crossOverProbs[1]</code>. <code>CrossOverProbs[0]</code> is effectively
082   * redundant as the cross would occur before the 1st position in the <code>SymbolList</code>.
083   *
084   * By convention if the array is shorter than the SymbolList it is being applied
085   * to then the last value in the array will be applied to every subsequent residue.
086   *
087   * The default value in all implementations should be <code>DEFAULT_CROSS_PROB</code>
088   *
089   * @param crossOverProbs an array of doubles giving the probability of a
090   * cross occuring at any place.
091   *
092   * @exception if a ChangeListener vetoes the change
093   */
094  public void setCrossOverProbs(double[] crossOverProbs) throws ChangeVetoException;
095  public double[] getCrossOverProbs();
096
097  public static final int DEFAULT_MAX_CROSS = Integer.MAX_VALUE;
098  public static final double[] DEFAULT_CROSS_PROB = {0.0};
099
100  public static final ChangeType MAX_CROSSES =
101      new ChangeType("maximum number of crosses",CrossOverFunction.class,"MAX_CROSSES");
102
103  public static final ChangeType CROSS_PROB =
104      new ChangeType("cross over probabilities",CrossOverFunction.class,"CROSS_PROB");
105
106  public static final CrossOverFunction NO_CROSS = new NoCross();
107
108
109
110  /**
111   * <p>A place holder CrossOverFunction that doesn't perform cross overs </p>
112   * @author Mark Schreiber
113   * @version 1.0
114   */
115  public final class NoCross implements CrossOverFunction {
116
117
118    /**
119     * @return a single member array equal to {0.0}
120     */
121    public double[] getCrossOverProbs(){
122      return new double[]{0.0};
123    }
124
125    /**
126     * @return 0 (after all you can't cross over with this function)
127     */
128    public int getMaxCrossOvers(){
129        return 0;
130    }
131
132    public GACrossResult performCrossOver(SymbolList chromA, SymbolList chromB){
133      return new SimpleGACrossResult(
134          new PointLocation[]{},
135          new SymbolList[]{chromA, chromB}
136          );
137    }
138
139    public void setCrossOverProbs(double[] crossOverProb) throws ChangeVetoException{
140      throw new ChangeVetoException("Cannot set the crossOverProb for a NO_CROSS function");
141    }
142
143    public void setMaxCrossOvers(int max) throws ChangeVetoException{
144      throw new ChangeVetoException("Cannot change the maximum crossovers in a NO_CROSS function");
145    }
146
147    public boolean isUnchanging(ChangeType t){
148      return true;
149    }
150
151    public void removeChangeListener(ChangeListener c){};
152    public void addChangeListener(ChangeListener cl){};
153    public void addChangeListener(ChangeListener cl, ChangeType ct){};
154    public void removeChangeListener(ChangeListener cl, ChangeType ct){};
155  }
156}