001    package org.jaga.reproduction.greycodedNumbers;
002    
003    import org.jaga.definitions.*;
004    import org.jaga.util.*;
005    
006    import org.jaga.individualRepresentation.greycodedNumbers.*;
007    import org.jaga.reproduction.*;
008    
009    /**
010     * TODO: Complete these comments.
011     *
012     * <p><u>Project:</u> JAGA - Java API for Genetic Algorithms.</p>
013     *
014     * <p><u>Company:</u> University College London and JAGA.Org
015     *    (<a href="http://www.jaga.org" target="_blank">http://www.jaga.org</a>).
016     * </p>
017     *
018     * <p><u>Copyright:</u> (c) 2004 by G. Paperin.<br/>
019     *    This program is free software; you can redistribute it and/or modify
020     *    it under the terms of the GNU General Public License as published by
021     *    the Free Software Foundation, ONLY if you include a note of the original
022     *    author(s) in any redistributed/modified copy.<br/>
023     *    This program is distributed in the hope that it will be useful,
024     *    but WITHOUT ANY WARRANTY; without even the implied warranty of
025     *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
026     *    GNU General Public License for more details.<br/>
027     *    You should have received a copy of the GNU General Public License
028     *    along with this program; if not, write to the Free Software
029     *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
030     *    or see http://www.gnu.org/licenses/gpl.html</p>
031     *
032     * @author Greg Paperin (greg@jaga.org)
033     *
034     * @version JAGA public release 1.0 beta
035     */
036    
037    public class SimpleBinaryMutation extends Mutation {
038    
039            private static final Class applicableClass = BinaryEncodedIndividual.class;
040    
041            public Class getApplicableClass() {
042                    return applicableClass;
043            }
044    
045            public SimpleBinaryMutation() {
046                    super();
047            }
048    
049            public SimpleBinaryMutation(double mutProb) {
050                    super(mutProb);
051            }
052    
053            public Individual [] reproduce(Individual[] parents, GAParameterSet params) {
054                    final int kidsCount = parents.length;
055                    BinaryEncodedIndividual [] kids = new BinaryEncodedIndividual[kidsCount];
056                    final RandomGenerator rnd = params.getRandomGenerator();
057                    final double mutProb = getMutationProbability();
058                    final NDecimalsIndividualSimpleFactory factory =
059                                    (NDecimalsIndividualSimpleFactory) params.getIndividualsFactory();
060    
061                    for (int i = 0; i < kidsCount; i++) {
062    
063                            final int maxAttempts = params.getMaxBadReproductionAttempts();
064                            int attempts = 0;
065                            boolean kidIsValid = false;
066                            do {
067    
068                                    if (!getApplicableClass().isInstance(parents[i]))
069                                            fireIllegalParentException(parents, i);
070    
071                                    BitString kidBits = (BitString) ((BinaryEncodedIndividual) parents[i]).getBitStringRepresentation().clone();
072                                    for (int b = 0; b < kidBits.getLength(); b++)
073                                            if (rnd.nextDouble() < mutProb)
074                                                    kidBits.flip(b);
075    
076                                    NDecimalsIndividual tst = (NDecimalsIndividual)
077                                                                    factory.createSpecificIndividual(kidBits, params);
078                                    kidIsValid = factory.valid(tst);
079    
080                                    if (kidIsValid)
081                                            kids[i] = tst;
082    
083                                    attempts++;
084                            } while(!kidIsValid && attempts <= maxAttempts);
085    
086                            if (!kidIsValid) {
087                                    kids[i] = (BinaryEncodedIndividual) factory.createSpecificIndividual(
088                                                                                            ((BinaryEncodedIndividual)parents[i]).getBitStringRepresentation(),
089                                                                                            params);
090                                    kids[i].setFitness(parents[i].getFitness());
091                            }
092    
093                    }
094    
095                    return kids;
096            }
097    
098            private void fireIllegalParentException(Individual[] parents, int i)
099                                                                                                                       throws IllegalArgumentException {
100                    throw new IllegalArgumentException("SimpleBinaryMutation works "
101                                                                                       + "only on parents of type " + getApplicableClass()
102                                                                                       +", but parent number " + i + " is of type "
103                                                                                       + parents[i].getClass().getName());
104            }
105    
106    }