GaussianMutator.java
001 /*
002  * Java Genetic Algorithm Library (jenetics-3.0.0).
003  * Copyright (c) 2007-2014 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@gmx.at)
019  */
020 package org.jenetics;
021 
022 import static java.lang.String.format;
023 import static org.jenetics.internal.math.random.indexes;
024 
025 import java.util.Random;
026 
027 import org.jenetics.internal.math.base;
028 import org.jenetics.internal.util.Equality;
029 import org.jenetics.internal.util.Hash;
030 
031 import org.jenetics.util.MSeq;
032 import org.jenetics.util.RandomRegistry;
033 
034 /**
035  * The GaussianMutator class performs the mutation of a {@link NumericGene}.
036  * This mutator picks a new value based on a Gaussian distribution around the
037  * current value of the gene. The variance of the new value (before clipping to
038  * the allowed gene range) will be
039  <p>
040  <img
041  *     src="doc-files/gaussian-mutator-var.gif"
042  *     alt="\hat{\sigma }^2 = \left ( \frac{ g_{max} - g_{min} }{4}\right )^2"
043  * >
044  </p>
045  * The new value will be cropped to the gene's boundaries.
046  *
047  *
048  @author <a href="mailto:franz.wilhelmstoetter@gmx.at">Franz Wilhelmstötter</a>
049  @since 1.0
050  @version 3.0 &mdash; <em>$Date: 2014-12-28 $</em>
051  */
052 public final class GaussianMutator<
053     extends NumericGene<?, G>,
054     extends Comparable<? super C>
055 >
056     extends Mutator<G, C>
057 {
058 
059     public GaussianMutator(final double probability) {
060         super(probability);
061     }
062 
063     public GaussianMutator() {
064         this(DEFAULT_ALTER_PROBABILITY);
065     }
066 
067     @Override
068     protected int mutate(final MSeq<G> genes, final double p) {
069         final Random random = RandomRegistry.getRandom();
070 
071         return (int)indexes(random, genes.length(), p)
072             .peek(i -> genes.set(i, mutate(genes.get(i), random)))
073             .count();
074     }
075 
076     G mutate(final G gene, final Random random) {
077         final double std =
078             (gene.getMax().doubleValue() - gene.getMin().doubleValue())*0.25;
079 
080         return gene.newInstance(base.clamp(
081             random.nextGaussian()*std + gene.doubleValue(),
082             gene.getMin().doubleValue(),
083             gene.getMax().doubleValue()
084         ));
085     }
086 
087     @Override
088     public int hashCode() {
089         return Hash.of(getClass()).and(super.hashCode()).value();
090     }
091 
092     @Override
093     public boolean equals(final Object obj) {
094         return Equality.of(this, obj).test(super::equals);
095     }
096 
097     @Override
098     public String toString() {
099         return format(
100             "%s[p=%f]",
101             getClass().getSimpleName(),
102             _probability
103         );
104     }
105 
106 }