| 
001 /*002  * Java Genetic Algorithm Library (jenetics-4.3.0).
 003  * Copyright (c) 2007-2018 Franz Wilhelmstötter
 004  *
 005  * Licensed under the Apache License, Version 2.0 (the "License");
 006  * you may not use this file except in compliance with the License.
 007  * You may obtain a copy of the License at
 008  *
 009  *      http://www.apache.org/licenses/LICENSE-2.0
 010  *
 011  * Unless required by applicable law or agreed to in writing, software
 012  * distributed under the License is distributed on an "AS IS" BASIS,
 013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 014  * See the License for the specific language governing permissions and
 015  * limitations under the License.
 016  *
 017  * Author:
 018  *    Franz Wilhelmstötter (franz.wilhelmstoetter@gmail.com)
 019  */
 020 package io.jenetics.ext;
 021
 022 import java.util.Random;
 023
 024 import io.jenetics.Chromosome;
 025 import io.jenetics.Gene;
 026 import io.jenetics.Mutator;
 027 import io.jenetics.MutatorResult;
 028 import io.jenetics.internal.math.probability;
 029 import io.jenetics.util.ISeq;
 030
 031 import io.jenetics.ext.util.FlatTree;
 032 import io.jenetics.ext.util.FlatTreeNode;
 033 import io.jenetics.ext.util.TreeNode;
 034
 035 /**
 036  * Abstract class for mutating tree chromosomes.
 037  *
 038  * @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a>
 039  * @version 4.1
 040  * @since 4.1
 041  */
 042 public abstract class TreeMutator<
 043     A,
 044     G extends TreeGene<A, G>,
 045     C extends Comparable<? super C>
 046 >
 047     extends Mutator<G, C>
 048 {
 049     public TreeMutator() {
 050         this(DEFAULT_ALTER_PROBABILITY);
 051     }
 052
 053     public TreeMutator(final double probability) {
 054         super(probability);
 055     }
 056
 057
 058     /**
 059      * Mutates the given chromosome.
 060      *
 061      * @see #mutate(Gene, Random)
 062      *
 063      * @param chromosome the chromosome to mutate
 064      * @param p the mutation probability for the underlying genetic objects
 065      * @param random the random engine used for the genotype mutation
 066      * @return the mutation result
 067      */
 068     @Override
 069     protected MutatorResult<Chromosome<G>> mutate(
 070         final Chromosome<G> chromosome,
 071         final double p,
 072         final Random random
 073     ) {
 074         final int P = probability.toInt(p);
 075         return random.nextInt() < P
 076             ? mutate(chromosome)
 077             : MutatorResult.of(chromosome);
 078     }
 079
 080     private MutatorResult<Chromosome<G>> mutate(final Chromosome<G> chromosome) {
 081         final TreeNode<A> tree = TreeNode.ofTree(chromosome.getGene());
 082         mutate(tree);
 083
 084         final FlatTreeNode<A> flat = FlatTreeNode.of(tree);
 085         final ISeq<G> genes = flat.map(t -> gene(chromosome.getGene(), t));
 086         return MutatorResult.of(chromosome.newInstance(genes), 1);
 087     }
 088
 089     private G gene(
 090         final G template,
 091         final FlatTree<? extends A, ?> tree
 092     ) {
 093         return template.newInstance(
 094             tree.getValue(),
 095             tree.childOffset(),
 096             tree.childCount()
 097         );
 098     }
 099
 100     /**
 101      * This method does the actual mutating, in place.
 102      *
 103      * @param tree the mutable tree to mutate
 104      */
 105     protected abstract void mutate(final TreeNode<A> tree);
 106
 107 }
 |