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 }