001/* 002 * Java Genetic Algorithm Library (jenetics-8.3.0). 003 * Copyright (c) 2007-2025 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 */ 020package io.jenetics; 021 022import static java.util.Objects.requireNonNull; 023 024import java.util.random.RandomGenerator; 025 026import io.jenetics.stat.Sampler; 027import io.jenetics.util.DoubleRange; 028 029/** 030 * A mutator which replaces a gene (mutates it) with a value created by a 031 * {@link Sampler}. 032 * 033 * @param <G> the gene type 034 * @param <C> the allele type 035 * 036 * @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a> 037 * @since 8.3 038 * @version 8.3 039 */ 040public class SamplerMutator< 041 G extends NumericGene<?, G>, 042 C extends Comparable<? super C> 043> 044 extends Mutator<G, C> 045{ 046 047 protected final Sampler sampler; 048 049 /** 050 * Create a new mutator with the given mutation {@code probability} and 051 * gene {@code sampler}. 052 * 053 * @param probability the mutation probability 054 * @param sampler the gene sampler for creating new gene values 055 */ 056 public SamplerMutator(final double probability, final Sampler sampler) { 057 super(probability); 058 this.sampler = requireNonNull(sampler); 059 } 060 061 /** 062 * Create a new mutator with the default mutation probability 063 * {@link #DEFAULT_ALTER_PROBABILITY} and gene {@code sampler}. 064 * 065 * @param sampler the gene sampler for creating new gene values 066 */ 067 public SamplerMutator(final Sampler sampler) { 068 this(DEFAULT_ALTER_PROBABILITY, sampler); 069 } 070 071 /** 072 * Create a new mutator with the given mutation {@code probability} and 073 * uniform gene sample, {@link Sampler#UNIFORM}. 074 * 075 * @param probability the mutation probability 076 */ 077 public SamplerMutator(final double probability) { 078 this(probability, Sampler.UNIFORM); 079 } 080 081 @Override 082 protected G mutate(final G gene, final RandomGenerator random) { 083 if (!gene.isValid()) { 084 return gene; 085 } 086 087 final var range = new DoubleRange( 088 gene.min().doubleValue(), 089 gene.max().doubleValue() 090 ); 091 final var next = sampler.sample(random, range); 092 return Double.isNaN(next) ? gene : gene.newInstance(next); 093 } 094 095}