001/* 002 * Java Genetic Algorithm Library (jenetics-8.1.0). 003 * Copyright (c) 2007-2024 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 io.jenetics.util.ISeq; 025import io.jenetics.util.Seq; 026 027/** 028 * The Alterer is responsible for the changing/recombining the Population. 029 * Alterers can be chained by appending a list of alterers with the 030 * {@link io.jenetics.engine.Engine.Builder#alterers(Alterer, Alterer[])} method. 031 * 032 * {@snippet lang="java": 033 * final Engine<DoubleGene, Double> engine = Engine 034 * .builder(gtf, ff) 035 * .alterers( 036 * new Crossover<>(0.1), 037 * new Mutator<>(0.05), 038 * new MeanAlterer<>(0.2)) 039 * .build(); 040 * final EvolutionStream<DoubleGene, Double> stream = engine.stream(); 041 * } 042 * 043 * The order of the alterer calls is: Crossover, Mutation and MeanAlterer. 044 * 045 * @param <G> the gene type 046 * @param <C> the fitness function result type 047 * 048 * @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a> 049 * @since 1.0 050 * @version 4.0 051 */ 052@FunctionalInterface 053public interface Alterer< 054 G extends Gene<?, G>, 055 C extends Comparable<? super C> 056> { 057 058 /** 059 * The default alter probability: 0.2 060 */ 061 double DEFAULT_ALTER_PROBABILITY = 0.2; 062 063 /** 064 * Alters (recombine) a given population. If the {@code population} is empty, 065 * nothing is altered. The altered population is part of the returned 066 * {@code AlterResult} object. 067 * 068 * @param population The Population to be altered. If the {@code population} 069 * is {@code null} or empty, nothing is altered. 070 * @param generation the date of birth (generation) of the altered phenotypes. 071 * @return the alter-result object, which contains the altered population 072 * and the alteration counts 073 * @throws NullPointerException if the given {@code population} is 074 * {@code null}. 075 */ 076 AltererResult<G, C> alter( 077 final Seq<Phenotype<G, C>> population, 078 final long generation 079 ); 080 081 /** 082 * Returns a composed alterer that first applies the {@code before} alterer 083 * to its input, and then applies {@code this} alterer to the result. 084 * 085 * @param before the alterer to apply first 086 * @return the new composed alterer 087 */ 088 default Alterer<G, C> compose(final Alterer<G, C> before) { 089 return of(requireNonNull(before), this); 090 } 091 092 /** 093 * Returns a composed alterer that applies the {@code this} alterer 094 * to its input, and then applies the {@code after} alterer to the result. 095 * 096 * @param after the alterer to apply first 097 * @return the new composed alterer 098 */ 099 default Alterer<G, C> andThen(final Alterer<G, C> after) { 100 return of(this, requireNonNull(after)); 101 } 102 103 /** 104 * Combine the given alterers. 105 * 106 * @param <G> the gene type 107 * @param <C> the fitness function result type 108 * @param alterers the alterers to combine. 109 * @return a new alterer which consists of the given one 110 * @throws NullPointerException if one of the alterers is {@code null}. 111 */ 112 @SafeVarargs 113 static <G extends Gene<?, G>, C extends Comparable<? super C>> 114 Alterer<G, C> of(final Alterer<G, C>... alterers) { 115 return alterers.length == 0 116 ? (p, g) -> new AltererResult<>(p.asISeq()) 117 : alterers.length == 1 118 ? alterers[0] 119 : new CompositeAlterer<>(ISeq.of(alterers)); 120 } 121 122}