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 java.util.ArrayList; 026import java.util.Random; 027 028import org.biojava.bio.BioError; 029import org.biojava.bio.symbol.Edit; 030import org.biojava.bio.symbol.IllegalAlphabetException; 031import org.biojava.bio.symbol.PointLocation; 032import org.biojava.bio.symbol.SymbolList; 033import org.biojava.utils.ChangeVetoException; 034 035/** 036 * <p>Simple Implementation of the <code>CrossOverFunction</code> interface</p> 037 * 038 * @author Mark Schreiber 039 * @version 1.0 040 * @since 1.5 041 */ 042 043public class SimpleCrossOverFunction extends AbstractCrossOverFunction { 044 045 public SimpleCrossOverFunction() { 046 } 047 048 049 // This is the one that actually does the work 050 public GACrossResult performCrossOver(SymbolList chromA, 051 SymbolList chromB) 052 throws ChangeVetoException { 053 054 ArrayList crossPoints = new ArrayList(); 055 Random rand = new Random(); 056 057 //do the actual crossing! 058 double crossProb; 059 //don't use <= crhomA.length() as there is no point crossing at the last pos 060 for (int i = 1; i < chromA.length() && i < chromB.length(); i++) { 061 062 //crossOverProbs might be shorter than i, in this case use the last prob 063 if(i - 1 > getCrossOverProbs().length -1) 064 crossProb = getCrossOverProbs()[getCrossOverProbs().length -1]; 065 else 066 crossProb = getCrossOverProbs()[i-1]; 067 068 if(crossPoints.size() >= getMaxCrossOvers()) 069 break; 070 071 if(rand.nextDouble() <= crossProb){ 072 073 074 //record the cross 075 crossPoints.add(new PointLocation(i)); 076 077 //do a cross over 078 SymbolList aReplace = chromB.subList(i, chromB.length()); 079 SymbolList bReplace = chromA.subList(i, chromA.length()); 080 081 //replace chromA from cross point down with chromB from crosspoint down 082 Edit ed = new Edit(i, aReplace.length(), aReplace); 083 try { 084 chromA.edit(ed); 085 }catch (IllegalAlphabetException ex) { 086 //can't happen 087 throw new BioError(ex); 088 } 089 090 //do the reciprocal 091 ed = new Edit(i, bReplace.length(), bReplace); 092 try { 093 chromB.edit(ed); 094 } 095 catch (IllegalAlphabetException ex) { 096 throw new BioError(ex); 097 } 098 } 099 } 100 101 102 PointLocation[] crosses = new PointLocation[crossPoints.size()]; 103 crosses = (PointLocation[])crossPoints.toArray(crosses); 104 return new SimpleGACrossResult(crosses, new SymbolList[]{chromA, chromB}); 105 } 106}