001    package org.jaga.reproduction.booleanFormulas;
002    
003    import org.jaga.reproduction.booleanFormulas.nodes.*;
004    import org.jaga.individualRepresentation.booleanFormulas.*;
005    import org.jaga.reproduction.Mutation;
006    import org.jaga.definitions.*;
007    
008    /**
009     * TODO: Complete these comments.
010     *
011     * <p><u>Project:</u> JAGA - Java API for Genetic Algorithms.</p>
012     *
013     * <p><u>Company:</u> University College London and JAGA.Org
014     *    (<a href="http://www.jaga.org" target="_blank">http://www.jaga.org</a>).
015     * </p>
016     *
017     * <p><u>Copyright:</u> (c) 2004 by G. Paperin.<br/>
018     *    This program is free software; you can redistribute it and/or modify
019     *    it under the terms of the GNU General Public License as published by
020     *    the Free Software Foundation, ONLY if you include a note of the original
021     *    author(s) in any redistributed/modified copy.<br/>
022     *    This program is distributed in the hope that it will be useful,
023     *    but WITHOUT ANY WARRANTY; without even the implied warranty of
024     *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
025     *    GNU General Public License for more details.<br/>
026     *    You should have received a copy of the GNU General Public License
027     *    along with this program; if not, write to the Free Software
028     *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
029     *    or see http://www.gnu.org/licenses/gpl.html</p>
030     *
031     * @author Greg Paperin (greg@jaga.org)
032     *
033     * @version JAGA public release 1.0 beta
034     */
035    
036    public class FunctionTreeMutation extends Mutation {
037    
038            private static final Class applicableClass = BooleanFormulaTree.class;
039    
040            public FunctionTreeMutation() {
041                    super();
042            }
043    
044            public FunctionTreeMutation(double mutProb) {
045                    super(mutProb);
046            }
047    
048            public Class getApplicableClass() {
049                    return applicableClass;
050            }
051    
052            public Individual[] reproduce(Individual[] parents, GAParameterSet params) {
053    
054                    Individual [] kids = new Individual[parents.length];
055                    for (int i = 0; i < kids.length; i++) {
056                            if (!getApplicableClass().isInstance(parents[i]))
057                                    throw new ClassCastException("Incompatible parent class: must be "
058                                                                                             + getApplicableClass().getName()
059                                                                                             + ", but is " + parents.getClass().getName());
060                            kids[i] = mutate((BooleanFormulaTree) parents[i], params);
061                    }
062                    return kids;
063            }
064    
065            private BooleanFormulaTree mutate(BooleanFormulaTree parent, GAParameterSet params) {
066    
067                    BooleanFormulaTree kid = createSpecificIndividual(parent, params);
068    
069                    if (params.getRandomGenerator().nextDouble() < getMutationProbability()) {
070                            final BooleanFormulaTreeFactory fact = fetchFactory(params);
071                            final Long handle = kid.selectRandomNode(params);
072                            int depth = kid.getNodeDepth(handle);
073                            BooleanFormulaTreeNode replacement = fact.createRandomNode(depth, params);
074                            kid.replaceNode(handle, replacement);
075                            kid.setFitness(null);
076                    }
077    
078                    return kid;
079            }
080    
081            private BooleanFormulaTree createSpecificIndividual(Object init, GAParameterSet params) {
082                    final BooleanFormulaTreeFactory fact = fetchFactory(params);
083                    final Individual form = (BooleanFormulaTree) fact.createSpecificIndividual(init, params);
084                    return (BooleanFormulaTree) form;
085            }
086    
087            private BooleanFormulaTreeFactory fetchFactory(GAParameterSet params) {
088                    return (BooleanFormulaTreeFactory) params.getIndividualsFactory();
089            }
090    
091    }