T
- the argument type of a given problemG
- the Gene
type used for encoding the argument type T
public interface Codec<T,G extends Gene<?,G>>
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.getChromosome().getGene().getAllele()
);
of(Factory, Function)
method is the usual way for
creating new Codec
instances.Codecs
,
Engine
,
Engine.Builder
Modifier and Type | Method and Description |
---|---|
default T |
decode(Genotype<G> genotype)
Converts the given
Genotype to the target type T . |
Function<Genotype<G>,T> |
decoder()
Return the decoder function which transforms the genotype back
to the original problem domain representation.
|
Factory<Genotype<G>> |
encoding()
Return the genotype factory for creating genotypes with the right
encoding for the given problem.
|
default <B> Codec<B,G> |
map(Function<? super T,? extends B> mapper)
Create a new
Codec with the mapped result type. |
static <G extends Gene<?,G>,A,B,T> |
of(Codec<A,G> codec1,
Codec<B,G> codec2,
BiFunction<A,B,T> decoder)
Converts two given
Codec instances into one. |
static <G extends Gene<?,G>,T> |
of(Factory<Genotype<G>> encoding,
Function<Genotype<G>,T> decoder)
Create a new
Codec object with the given encoding and
decoder function. |
static <G extends Gene<?,G>,T> |
of(ISeq<? extends Codec<?,G>> codecs,
Function<? super Object[],? extends T> decoder)
Combines the given
codecs into one codec. |
Factory<Genotype<G>> encoding()
decoder()
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);
decoder()
Function<Genotype<G>,T> decoder()
encoding()
default T decode(Genotype<G> genotype)
Genotype
to the target type T
. This is
a shortcut for
final Codec<SomeObject, DoubleGene> codec = ...
final Genotype<DoubleGene> gt = codec.encoding().newInstance();
final SomeObject arg = codec.decoder().apply(gt);
genotype
- the genotype to be convertedNullPointerException
- if the given genotype
is null
default <B> Codec<B,G> map(Function<? super T,? extends B> mapper)
Codec
with the mapped result type. The following
example creates a double codec who's values are not uniformly distributed
between [0..1)
. Instead the values now follow an exponential
function.
final Codec<Double, DoubleGene> c = Codecs.ofScalar(DoubleRange.of(0, 1))
.map(Math::exp);
B
- the new argument type of the given problemmapper
- the mapper functionCodec
with the mapped result typeNullPointerException
- if the mapper is null
.static <G extends Gene<?,G>,T> Codec<T,G> of(Factory<Genotype<G>> encoding, Function<Genotype<G>,T> decoder)
Codec
object with the given encoding
and
decoder
function.G
- the Gene
typeT
- the fitness function argument type in the problem domainencoding
- the genotype factory used for creating new
Genotypes
.decoder
- decoder function, which converts a Genotype
to a
value in the problem domain.Codec
object with the given parameters.NullPointerException
- if one of the arguments is null
.static <G extends Gene<?,G>,A,B,T> Codec<T,G> of(Codec<A,G> codec1, Codec<B,G> codec2, BiFunction<A,B,T> decoder)
Codec
instances into one. This lets you divide
a problem into sub problems and combine them again.
The following example shows how to combine two codecs, which converts a
LongGene
to a LocalDate
, to a codec which combines the
two LocalDate
object (this are the argument types of the
component codecs) to a Duration
.
final Codec<LocalDate, LongGene> dateCodec1 = Codec.of(
Genotype.of(LongChromosome.of(0, 10_000)),
gt -> LocalDate.ofEpochDay(gt.getGene().longValue())
);
final Codec<LocalDate, LongGene> dateCodec2 = Codec.of(
Genotype.of(LongChromosome.of(1_000_000, 10_000_000)),
gt -> LocalDate.ofEpochDay(gt.getGene().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.getGenotype());
System.out.println(duration);
G
- the gene typeA
- the argument type of the first codecB
- the argument type of the second codecT
- the argument type of the compound codeccodec1
- the first codeccodec2
- the second codecdecoder
- the decoder which combines the two argument types from the
given given codecs, to the argument type of the resulting codec.codec1
and
codec2
NullPointerException
- if one of the arguments is null
static <G extends Gene<?,G>,T> Codec<T,G> of(ISeq<? extends Codec<?,G>> codecs, Function<? super Object[],? extends T> decoder)
codecs
into one codec. This lets you divide
a problem into sub problems 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.getGenotype());
System.out.println(duration);
G
- the gene typeT
- the argument type of the compound codeccodecs
- the Codec
sequence of the sub-problemsdecoder
- the decoder which combines the argument types from the
given given codecs, to the argument type of the resulting codec.codecs
NullPointerException
- if one of the arguments is null
© 2007-2018 Franz Wilhelmstötter (2018-10-28 17:23)