/** * Create a new {@code Codec} with the mapped result type. The following * example creates a double codec who's values are not uniformly distributed * between {@code [0..1)}. Instead the values now follow an exponential * function. * * <pre>{@code * final Codec<Double, DoubleGene> c = Codecs.ofScalar(DoubleRange.of(0, 1)) * .map(Math::exp); * }</pre> * * @since 4.0 * * @param mapper the mapper function * @param <B> the new argument type of the given problem * @return a new {@code Codec} with the mapped result type * @throws NullPointerException if the mapper is {@code null}. */ public default <B> Codec<B, G> map(final Function<? super T, ? extends B> mapper) { requireNonNull(mapper); return Codec.of( encoding(), gt -> mapper.apply(decode(gt)) ); }
/** * Create a new evolution {@code Engine.Builder} with the given fitness * function and problem {@code codec}. * * @since 3.2 * * @param ff the fitness function * @param codec the problem codec * @param <T> the fitness function input type * @param <C> the fitness function result type * @param <G> the gene type * @return a new engine builder * @throws java.lang.NullPointerException if one of the arguments is * {@code null}. */ public static <T, G extends Gene<?, G>, C extends Comparable<? super C>> Builder<G, C> builder( final Function<? super T, ? extends C> ff, final Codec<T, G> codec ) { return builder(ff.compose(codec.decoder()), codec.encoding()); }
public static void main(final String[] args) { final ISeq<Genotype<DoubleGene>> population = RandomRegistry.with(new Random(123), r -> CODEC.encoding().instances() .limit(10) .collect(ISeq.toISeq()) ); final Engine<DoubleGene, Double> engine = Engine.builder(Function.identity(), CODEC) .executor(Runnable::run) .build(); final EvolutionResult<DoubleGene, Double> result = RandomRegistry.with(new Random(456), r -> engine.stream(population) .limit(100) .collect(EvolutionResult.toBestEvolutionResult()) ); System.out.println(result.getBestPhenotype()); }
@Test public void ofAnyScalar2() { final Codec<Integer, AnyGene<Integer>> codec = Codecs.ofScalar( () -> RandomRegistry.getRandom().nextInt(1000) ); for (int i = 0; i < 1000; ++i) { final AnyGene<Integer> gene = codec.encoding() .newInstance().getGene(); Assert.assertTrue(gene.isValid()); Assert.assertTrue(gene.getAllele() < 1000); Assert.assertTrue(gene.getAllele() >= 0); } }
@Test(dataProvider = "intScalarData") public void ofIntScalar(final IntRange domain) { final Codec<Integer, IntegerGene> codec = Codecs.ofScalar(domain); final Genotype<IntegerGene> gt = codec.encoding().newInstance(); Assert.assertEquals(gt.length(), 1); Assert.assertEquals(gt.getChromosome().length(), 1); Assert.assertEquals(gt.getGene().getMin().intValue(), domain.getMin()); Assert.assertEquals(gt.getGene().getMax().intValue(), domain.getMax()); final Function<Genotype<IntegerGene>, Integer> f = codec.decoder(); Assert.assertEquals(f.apply(gt).intValue(), gt.getGene().intValue()); }
@Test(dataProvider = "longScalarData") public void ofLongScalar(final LongRange domain) { final Codec<Long, LongGene> codec = Codecs.ofScalar(domain); final Genotype<LongGene> gt = codec.encoding().newInstance(); Assert.assertEquals(gt.length(), 1); Assert.assertEquals(gt.getChromosome().length(), 1); Assert.assertEquals(gt.getGene().getMin().longValue(), domain.getMin()); Assert.assertEquals(gt.getGene().getMax().longValue(), domain.getMax()); final Function<Genotype<LongGene>, Long> f = codec.decoder(); Assert.assertEquals(f.apply(gt).longValue(), gt.getGene().longValue()); }
@Test public void ofAnyScalar() { final Codec<Integer, AnyGene<Integer>> codec = Codecs.ofScalar( () -> RandomRegistry.getRandom().nextInt(1000), i -> i < 100 ); for (int i = 0; i < 1000; ++i) { final AnyGene<Integer> gene = codec.encoding() .newInstance().getGene(); Assert.assertEquals(gene.isValid(), gene.getAllele() < 100); Assert.assertTrue(gene.getAllele() < 1000); Assert.assertTrue(gene.getAllele() >= 0); } }
@Test public void ofSubSet() { final Codec<ISeq<String>, EnumGene<String>> codec = Codecs.ofSubSet( ISeq.of("1", "2", "3", "4", "5"), 3 ); for (int i = 0; i < 100; ++i) { final Genotype<EnumGene<String>> gt = codec.encoding().newInstance(); final Chromosome<EnumGene<String>> ch = gt.getChromosome(); Assert.assertEquals(ch.length(), 3); Assert.assertTrue(ch.isValid()); final ISeq<String> permutation = codec.decoder().apply(gt); Assert.assertEquals(permutation.length(), 3); } }
@Test(dataProvider = "intVectorData") public void ofIntVector(final IntRange domain, final int length) { final Codec<int[], IntegerGene> codec = Codecs.ofVector(domain, length); final Genotype<IntegerGene> gt = codec.encoding().newInstance(); Assert.assertEquals(gt.length(), 1); Assert.assertEquals(gt.getChromosome().length(), length); for (IntegerGene gene : gt.getChromosome()) { Assert.assertEquals(gene.getMin().intValue(), domain.getMin()); Assert.assertEquals(gene.getMax().intValue(), domain.getMax()); } final Function<Genotype<IntegerGene>, int[]> f = codec.decoder(); final int[] value = f.apply(gt); Assert.assertEquals(value.length, length); for (int i = 0; i < length; ++i) { Assert.assertEquals(gt.get(0, i).intValue(), value[i]); } }
@Test(dataProvider = "longVectorData") public void ofLongVector(final LongRange domain, final int length) { final Codec<long[], LongGene> codec = Codecs.ofVector(domain, length); final Genotype<LongGene> gt = codec.encoding().newInstance(); Assert.assertEquals(gt.length(), 1); Assert.assertEquals(gt.getChromosome().length(), length); for (LongGene gene : gt.getChromosome()) { Assert.assertEquals(gene.getMin().longValue(), domain.getMin()); Assert.assertEquals(gene.getMax().longValue(), domain.getMax()); } final Function<Genotype<LongGene>, long[]> f = codec.decoder(); final long[] value = f.apply(gt); Assert.assertEquals(value.length, length); for (int i = 0; i < length; ++i) { Assert.assertEquals(gt.get(0, i).longValue(), value[i]); } }
@Test(dataProvider = "doubleScalarData") public void ofDoubleScalar(final DoubleRange domain) { final Codec<Double, DoubleGene> codec = Codecs.ofScalar(domain); final Genotype<DoubleGene> gt = codec.encoding().newInstance(); Assert.assertEquals(gt.length(), 1); Assert.assertEquals(gt.getChromosome().length(), 1); Assert.assertEquals(gt.getGene().getMin(), domain.getMin()); Assert.assertEquals(gt.getGene().getMax(), domain.getMax()); final Function<Genotype<DoubleGene>, Double> f = codec.decoder(); Assert.assertEquals(f.apply(gt), gt.getGene().doubleValue()); }
@Test(dataProvider = "longVectorDataVector") public void ofLongVectorVector(final LongRange[] domain) { final Codec<long[], LongGene> codec = Codecs.ofVector(domain); final Genotype<LongGene> gt = codec.encoding().newInstance(); Assert.assertEquals(gt.length(), domain.length); for (int i = 0; i < gt.length(); ++i) { final Chromosome<LongGene> ch = gt.getChromosome(i); Assert.assertEquals(ch.length(), 1); final LongGene gene = ch.getGene(); Assert.assertEquals(gene.getMin().longValue(), domain[i].getMin()); Assert.assertEquals(gene.getMax().longValue(), domain[i].getMax()); } final Function<Genotype<LongGene>, long[]> f = codec.decoder(); final long[] value = f.apply(gt); Assert.assertEquals(value.length, domain.length); for (int i = 0; i < domain.length; ++i) { Assert.assertEquals(gt.get(i, 0).longValue(), value[i]); } }
@Test(dataProvider = "intVectorDataVector") public void ofIntVectorVector(final IntRange[] domain) { final Codec<int[], IntegerGene> codec = Codecs.ofVector(domain); final Genotype<IntegerGene> gt = codec.encoding().newInstance(); Assert.assertEquals(gt.length(), domain.length); for (int i = 0; i < gt.length(); ++i) { final Chromosome<IntegerGene> ch = gt.getChromosome(i); Assert.assertEquals(ch.length(), 1); final IntegerGene gene = ch.getGene(); Assert.assertEquals(gene.getMin().intValue(), domain[i].getMin()); Assert.assertEquals(gene.getMax().intValue(), domain[i].getMax()); } final Function<Genotype<IntegerGene>, int[]> f = codec.decoder(); final int[] value = f.apply(gt); Assert.assertEquals(value.length, domain.length); for (int i = 0; i < domain.length; ++i) { Assert.assertEquals(gt.get(i, 0).intValue(), value[i]); } }
@Test(dataProvider = "doubleVectorData") public void ofDoubleVector(final DoubleRange domain, final int length) { final Codec<double[], DoubleGene> codec = Codecs.ofVector(domain, length); final Genotype<DoubleGene> gt = codec.encoding().newInstance(); Assert.assertEquals(gt.length(), 1); Assert.assertEquals(gt.getChromosome().length(), length); for (DoubleGene gene : gt.getChromosome()) { Assert.assertEquals(gene.getMin(), domain.getMin()); Assert.assertEquals(gene.getMax(), domain.getMax()); } final Function<Genotype<DoubleGene>, double[]> f = codec.decoder(); final double[] value = f.apply(gt); Assert.assertEquals(value.length, length); for (int i = 0; i < length; ++i) { Assert.assertEquals(gt.get(0, i).doubleValue(), value[i]); } }
private Phenotype<DoubleGene, Vec<double[]>> phenotype() { return Phenotype.of( PROBLEM.codec().encoding().newInstance(), 1L, gt -> PROBLEM.fitness().apply(PROBLEM.codec().decode(gt)) ); }
private Phenotype<DoubleGene, Vec<double[]>> phenotype() { return Phenotype.of( PROBLEM.codec().encoding().newInstance(), 1L, gt -> PROBLEM.fitness().apply(PROBLEM.codec().decode(gt)) ); }
@Test public void ofPermutation() { final Codec<ISeq<String>, EnumGene<String>> codec = Codecs .ofPermutation(ISeq.of("foo", "bar", "zoo")); final Genotype<EnumGene<String>> gt = codec.encoding().newInstance(); Assert.assertEquals(gt.length(), 1); final Function<Genotype<EnumGene<String>>, ISeq<String>> f = codec.decoder(); final ISeq<String> value = f.apply(gt); Assert.assertEquals(value.length(), gt.getChromosome().length()); for (int i = 0; i < value.length(); ++i) { Assert.assertEquals(value.get(i), gt.get(0, i).toString()); } }
@Test public void ofAnyVector() { final int length = 23; final Codec<ISeq<Integer>, AnyGene<Integer>> codec = Codecs.ofVector( () -> RandomRegistry.getRandom().nextInt(1000), (Predicate<Integer>) i -> i < 100, length ); for (int i = 0; i < 100; ++i) { final Chromosome<AnyGene<Integer>> ch = codec.encoding() .newInstance().getChromosome(); Assert.assertEquals(ch.length(), length); for (AnyGene<Integer> gene : ch) { Assert.assertEquals(gene.isValid(), gene.getAllele() < 100); if (!gene.isValid()) { Assert.assertFalse(ch.isValid()); } Assert.assertTrue(gene.getAllele() < 1000); Assert.assertTrue(gene.getAllele() >= 0); } } }
@Test(dataProvider = "doubleVectorDataVector") public void ofDoubleVectorVector(final DoubleRange[] domain) { final Codec<double[], DoubleGene> codec = Codecs.ofVector(domain); final Genotype<DoubleGene> gt = codec.encoding().newInstance(); Assert.assertEquals(gt.length(), domain.length); for (int i = 0; i < gt.length(); ++i) { final Chromosome<DoubleGene> ch = gt.getChromosome(i); Assert.assertEquals(ch.length(), 1); final DoubleGene gene = ch.getGene(); Assert.assertEquals(gene.getMin(), domain[i].getMin()); Assert.assertEquals(gene.getMax(), domain[i].getMax()); } final Function<Genotype<DoubleGene>, double[]> f = codec.decoder(); final double[] value = f.apply(gt); Assert.assertEquals(value.length, domain.length); for (int i = 0; i < domain.length; ++i) { Assert.assertEquals(gt.get(i, 0).doubleValue(), value[i]); } }
@Test public void encoding() { final Codec<Double, DoubleGene> codec = new CompositeCodec<>( ISeq.of( Codecs.ofScalar(DoubleRange.of(0, 1)), Codecs.ofVector(DoubleRange.of(10, 100), 3), Codecs.ofScalar(DoubleRange.of(2, 3)), Codecs.ofVector(DoubleRange.of(200, 500), DoubleRange.of(200, 500)) ), values -> { final Double v1 = (Double)values[0]; final double[] v2 = (double[])values[1]; final Double v3 = (Double)values[2]; final double[] v4 = (double[])values[3]; return v1 + DoubleAdder.sum(v2) + v3 + DoubleAdder.sum(v4); } ); final Genotype<DoubleGene> gt = codec.encoding().newInstance(); final double sum = gt.stream() .mapToDouble(c -> c.stream() .mapToDouble(DoubleGene::doubleValue) .sum()) .sum(); Assert.assertEquals(sum, codec.decoder().apply(gt), 0.000001); }