- Type Parameters:
T- the argument type of given problemG- theGenetype used for encoding the argument typeT
- All Known Subinterfaces:
InvertibleCodec<T,G>
A problem
The
Calling the
Codec contains the information about how to encode a given
argument type into a Genotype. It also lets convert the encoded
Genotype back to the argument type. The engine creation and the
implementation of the fitness function can be heavily simplified by using
a Codec class. The example given in the Engine documentation
can be simplified as follows:
public class RealFunction {
// The conversion from the 'Genotype' to the argument type of the fitness
// function is performed by the given 'Codec'. You can concentrate on the
// implementation, because you are not bothered with the conversion code.
private static double eval(final double x) {
return cos(0.5 + sin(x)) * cos(x);
}
public static void main(final String[] args) {
final Engine<DoubleGene, Double> engine = Engine
// Create an Engine.Builder with the "pure" fitness function
// and the appropriate Codec.
.build(RealFunction::eval, Codecs.ofScalar(DoubleRange.of(0, 2*PI)))
.build();
// ...
}
}
Codec needed for the above usage example, will look like this:
final DoubleRange domain = DoubleRange.of(0, 2*PI);
final Codec<Double, DoubleGene> codec = Codec.of(
Genotype.of(DoubleChromosome.of(domain)),
gt -> gt.chromosome().gene().allele()
);
of(Factory, Function) method is the usual way for
creating new Codec instances.- Since:
- 3.2
- Version:
- 3.6
- See Also:
-
Method Summary
Modifier and TypeMethodDescriptioncombine(Codec<? extends A, G> codec1, Codec<? extends B, G> codec2, BiFunction<? super A, ? super B, ? extends T> decoder) Converts two givenCodecinstances into one.Combines the givencodecsinto one codec.default Tdecoder()Return the decoder function which transforms the genotype back to the original problem domain representation.encoding()Return the genotype factory for creating genotypes with the right encoding for the given problem.Create a newCodecwith the mapped result type.of(Codec<A, G> codec1, Codec<B, G> codec2, BiFunction<A, B, T> decoder) Deprecated, for removal: This API element is subject to removal in a future version.Create a newCodecobject with the givenencodinganddecoderfunction.Deprecated, for removal: This API element is subject to removal in a future version.Will be removed in the next major version, usecombine(ISeq, Function)insteaddefault InvertibleCodec<T, G> toInvertibleCodec(Function<? super T, Genotype<G>> encoder) Converts this codec into an invertible codec, by using the givenencoder(inversion) function.
-
Method Details
-
encoding
Return the genotype factory for creating genotypes with the right encoding for the given problem. The genotype created with this factory must work together with thedecoder()function, which transforms the genotype into an object of the problem domain.final Codec<SomeObject, DoubleGene> codec = ...; final Genotype<DoubleGene> gt = codec.encoding().newInstance(); final SomeObject arg = codec.decoder().apply(gt);- Returns:
- the genotype (factory) representation of the problem domain
- See Also:
-
decoder
Return the decoder function which transforms the genotype back to the original problem domain representation.- Returns:
- genotype decoder
- See Also:
-
decode
Converts the givenGenotypeto the target typeCodec. This is a shortcut forfinal Codec<SomeObject, DoubleGene> codec = ...; final Genotype<DoubleGene> gt = codec.encoding().newInstance(); final SomeObject arg = codec.decoder().apply(gt);- Parameters:
genotype- the genotype to be converted- Returns:
- the converted genotype
- Throws:
NullPointerException- if the givengenotypeisnull- Since:
- 3.6
-
map
Create a newCodecwith the mapped result type. The following example creates a double codec whose values are not uniformly distributed between[0..1). Instead, the values now follow an exponential function.This method can also be used for creating non-trivial codes like split ranges, as shown in the following example, where only values between [0, 2) and [8, 10) are valid.final Codec<Double, DoubleGene> c = Codecs.ofScalar(DoubleRange.of(0, 1)) .map(Math::exp);+--+--+--+--+--+--+--+--+--+--+ | | | | | | | | | | | 0 1 2 3 4 5 6 7 8 9 10 |-----|xxxxxxxxxxxxxxxxx|-----| ^ |llllllll|rrrrrrrr| ^ | | | | +-------+ +------+final Codec<Double, DoubleGene> codec = Codecs .ofScalar(DoubleRange.of(0, 10)) .map(v -> { if (v >= 2 && v < 8) { return v < 5 ? ((v - 2)/3)*2 : ((8 - v)/3)*2 + 8; } return v; });- Type Parameters:
B- the new argument type of the given problem- Parameters:
mapper- the mapper function- Returns:
- a new
Codecwith the mapped result type - Throws:
NullPointerException- if the mapper isnull.- Since:
- 4.0
- See Also:
-
toInvertibleCodec
Converts this codec into an invertible codec, by using the givenencoder(inversion) function.- Parameters:
encoder- the (inverse) encoder function- Returns:
- a new invertible codec
- Throws:
NullPointerException- if the givenencoderisnull
-
of
static <T,G extends Gene<?, Codec<T,G>> G> of(Factory<Genotype<G>> encoding, Function<? super Genotype<G>, ? extends T> decoder) Create a newCodecobject with the givenencodinganddecoderfunction.- Type Parameters:
T- the fitness function argument type in the problem domainG- theGenetype- Parameters:
encoding- the genotype factory used for creating newGenotypesdecoder- decoder function, which converts aGenotypeto a value in the problem domain- Returns:
- a new
Codecobject with the given parameters - Throws:
NullPointerException- if one of the arguments isnull.
-
of
@Deprecated(since="8.1", forRemoval=true) static <A,B, Codec<T,T, G extends Gene<?, G>> G> of(Codec<A, G> codec1, Codec<B, G> codec2, BiFunction<A, B, T> decoder) Deprecated, for removal: This API element is subject to removal in a future version.Will be removed in the next major version, usecombine(Codec, Codec, BiFunction)insteadConverts two givenCodecinstances into one. This lets you divide a problem into subproblems and combine them again.The following example shows how to combine two codecs, which converts a
LongGeneto aLocalDate, to a codec which combines the twoLocalDateobject (these are the argument types of the component codecs) to aDuration.final Codec<LocalDate, LongGene> dateCodec1 = Codec.of( Genotype.of(LongChromosome.of(0, 10_000)), gt -> LocalDate.ofEpochDay(gt.gene().longValue()) ); final Codec<LocalDate, LongGene> dateCodec2 = Codec.of( Genotype.of(LongChromosome.of(1_000_000, 10_000_000)), gt -> LocalDate.ofEpochDay(gt.gene().longValue()) ); final Codec<Duration, LongGene> durationCodec = Codec.of( dateCodec1, dateCodec2, (d1, d2) -> Duration.ofDays(d2.toEpochDay() - d1.toEpochDay()) ); final Engine<LongGene, Long> engine = Engine .builder(Duration::toMillis, durationCodec) .build(); final Phenotype<LongGene, Long> pt = engine.stream() .limit(100) .collect(EvolutionResult.toBestPhenotype()); System.out.println(pt); final Duration duration = durationCodec.decoder() .apply(pt.genotype()); System.out.println(duration);- Type Parameters:
A- the argument type of the first codecB- the argument type of the second codecT- the argument type of the compound codecG- the gene type- Parameters:
codec1- the first codeccodec2- the second codecdecoder- the decoder which combines the two argument types from the given codecs, to the argument type of the resulting codec.- Returns:
- a new codec which combines the given
codec1andcodec2 - Throws:
NullPointerException- if one of the arguments isnull- Since:
- 3.3
- See Also:
-
combine
static <A,B, Codec<T,T, G extends Gene<?, G>> G> combine(Codec<? extends A, G> codec1, Codec<? extends B, G> codec2, BiFunction<? super A, ? super B, ? extends T> decoder) Converts two givenCodecinstances into one. This lets you divide a problem into subproblems and combine them again.The following example shows how to combine two codecs, which converts a
LongGeneto aLocalDate, to a codec which combines the twoLocalDateobject (these are the argument types of the component codecs) to aDuration.final Codec<LocalDate, LongGene> dateCodec1 = Codec.of( Genotype.of(LongChromosome.of(0, 10_000)), gt -> LocalDate.ofEpochDay(gt.gene().longValue()) ); final Codec<LocalDate, LongGene> dateCodec2 = Codec.of( Genotype.of(LongChromosome.of(1_000_000, 10_000_000)), gt -> LocalDate.ofEpochDay(gt.gene().longValue()) ); final Codec<Duration, LongGene> durationCodec = Codec.combine( dateCodec1, dateCodec2, (d1, d2) -> Duration.ofDays(d2.toEpochDay() - d1.toEpochDay()) ); final Engine<LongGene, Long> engine = Engine .builder(Duration::toMillis, durationCodec) .build(); final Phenotype<LongGene, Long> pt = engine.stream() .limit(100) .collect(EvolutionResult.toBestPhenotype()); System.out.println(pt); final Duration duration = durationCodec.decoder() .apply(pt.genotype()); System.out.println(duration);- Type Parameters:
A- the argument type of the first codecB- the argument type of the second codecT- the argument type of the compound codecG- the gene type- Parameters:
codec1- the first codeccodec2- the second codecdecoder- the decoder which combines the two argument types from the given codecs, to the argument type of the resulting codec.- Returns:
- a new codec which combines the given
codec1andcodec2 - Throws:
NullPointerException- if one of the arguments isnull- Since:
- 8.1
-
of
@Deprecated(since="8.1", forRemoval=true) static <T,G extends Gene<?, Codec<T,G>> G> of(ISeq<? extends Codec<?, G>> codecs, Function<? super Object[], ? extends T> decoder) Deprecated, for removal: This API element is subject to removal in a future version.Will be removed in the next major version, usecombine(ISeq, Function)insteadCombines the givencodecsinto one codec. This lets you divide a problem into subproblems and combine them again.The following example combines more than two sub-codecs into one.
final Codec<LocalDate, LongGene> dateCodec = Codec.of( Genotype.of(LongChromosome.of(0, 10_000)), gt -> LocalDate.ofEpochDay(gt.getGene().longValue()) ); final Codec<Duration, LongGene> durationCodec = Codec.of( ISeq.of(dateCodec, dateCodec, dateCodec), dates -> { final LocalDate ld1 = (LocalDate)dates[0]; final LocalDate ld2 = (LocalDate)dates[1]; final LocalDate ld3 = (LocalDate)dates[2]; return Duration.ofDays( ld1.toEpochDay() + ld2.toEpochDay() - ld3.toEpochDay() ); } ); final Engine<LongGene, Long> engine = Engine .builder(Duration::toMillis, durationCodec) .build(); final Phenotype<LongGene, Long> pt = engine.stream() .limit(100) .collect(EvolutionResult.toBestPhenotype()); System.out.println(pt); final Duration duration = durationCodec.decoder() .apply(pt.genotype()); System.out.println(duration);- Type Parameters:
T- the argument type of the compound codecG- the gene type- Parameters:
codecs- theCodecsequence of the subproblemsdecoder- the decoder which combines the argument types from the given codecs, to the argument type of the resulting codec.- Returns:
- a new codec which combines the given
codecs - Throws:
NullPointerException- if one of the arguments isnullIllegalArgumentException- if the givencodecssequence is empty- Since:
- 3.3
-
combine
static <T,G extends Gene<?, Codec<T,G>> G> combine(ISeq<? extends Codec<?, G>> codecs, Function<? super Object[], ? extends T> decoder) Combines the givencodecsinto one codec. This lets you divide a problem into subproblems and combine them again.The following example combines more than two sub-codecs into one.
final Codec<LocalDate, LongGene> dateCodec = Codec.of( Genotype.of(LongChromosome.of(0, 10_000)), gt -> LocalDate.ofEpochDay(gt.getGene().longValue()) ); final Codec<Duration, LongGene> durationCodec = Codec.combine( ISeq.of(dateCodec, dateCodec, dateCodec), dates -> { final LocalDate ld1 = (LocalDate)dates[0]; final LocalDate ld2 = (LocalDate)dates[1]; final LocalDate ld3 = (LocalDate)dates[2]; return Duration.ofDays( ld1.toEpochDay() + ld2.toEpochDay() - ld3.toEpochDay() ); } ); final Engine<LongGene, Long> engine = Engine .builder(Duration::toMillis, durationCodec) .build(); final Phenotype<LongGene, Long> pt = engine.stream() .limit(100) .collect(EvolutionResult.toBestPhenotype()); System.out.println(pt); final Duration duration = durationCodec.decoder() .apply(pt.genotype()); System.out.println(duration);- Type Parameters:
T- the argument type of the compound codecG- the gene type- Parameters:
codecs- theCodecsequence of the subproblemsdecoder- the decoder which combines the argument types from the given codecs, to the argument type of the resulting codec.- Returns:
- a new codec which combines the given
codecs - Throws:
NullPointerException- if one of the arguments isnullIllegalArgumentException- if the givencodecssequence is empty- Since:
- 8.1
-
combine(Codec, Codec, BiFunction)instead