/** * 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()); }
requireNonNull(mapSupplier); return ofPermutation(target.size()) .map(perm -> toMapping(perm, source, target, mapSupplier));
v -> decoder.apply((A)v[0], (B)v[1]); return of( ISeq.of(codec1, codec2), decoderAdapter
public static void main(final String[] args) { final Codec<Player, DoubleGene> codec = Codec.of( Genotype.of(DoubleChromosome.of(0, 1)), gt -> Player.of(gt.getGene().doubleValue()) if (pop != null) { final int index = RandomRegistry.getRandom().nextInt(pop.size()); other = codec.decode(pop.get(index).getGenotype()); } else { other = Player.of(0.5); .build(); final Player best = codec.decode( engine.stream() .limit(Limits.bySteadyFitness(50))
/** * Converts the given {@link Genotype} to the target type {@link T}. This is * a shortcut for * <pre>{@code * final Problem<SomeObject, DoubleGene, Double> problem = ... * final Genotype<DoubleGene> gt = problem.codec().encoding().newInstance(); * * final SomeObject arg = problem.decode(gt); * }</pre> * * @since 4.2 * * @see Codec#decode(Genotype) * * @param genotype the genotype to be converted * @return the converted genotype * @throws NullPointerException if the given {@code genotype} is {@code null} */ public default T decode(final Genotype<G> genotype) { return codec().decode(genotype); }
/** * Combines the given {@code codecs} into one codec. This lets you divide * a problem into sub problems and combine them again. * * @param codecs the {@code Codec} sequence of the sub-problems * @param decoder the decoder which combines the argument types from the * given given codecs, to the argument type of the resulting codec. * @throws NullPointerException if one of the arguments is {@code null} */ CompositeCodec( final ISeq<? extends Codec<?, G>> codecs, final Function<? super Object[], ? extends T> decoder ) { _codecs = requireNonNull(codecs); _decoder = requireNonNull(decoder); final ISeq<Genotype<G>> genotypes = _codecs .map(c -> c.encoding() instanceof Genotype ? (Genotype<G>)c.encoding() : c.encoding().newInstance()); _lengths = genotypes.stream() .mapToInt(Genotype::length) .toArray(); _encoding = Genotype.of( genotypes.stream() .flatMap(Genotype::stream) .collect(ISeq.toISeq()) ); }
/** * Converts the given {@link Genotype} to the target type {@link T}. This is * a shortcut for * <pre>{@code * final Codec<SomeObject, DoubleGene> codec = ... * final Genotype<DoubleGene> gt = codec.encoding().newInstance(); * * final SomeObject arg = codec.decoder().apply(gt); * }</pre> * * @since 3.6 * * @param genotype the genotype to be converted * @return the converted genotype * @throws NullPointerException if the given {@code genotype} is {@code null} */ public default T decode(final Genotype<G> genotype) { Objects.requireNonNull(genotype); return decoder().apply(genotype); }
@Test public void map() { final Codec<double[], DoubleGene> codec = Codecs .ofVector(DoubleRange.of(0, 1), 10) .map(v -> { for (int i = 0; i < v.length; ++i) { v[i] = v[i]/2.0; } return v; }); for (int i = 0; i < 100; ++i) { final Genotype<DoubleGene> gt = Genotype.of(DoubleChromosome.of( DoubleGene.of(i, DoubleRange.of(0, 100)) )); Assert.assertEquals(codec.decode(gt), new double[]{i/2.0}); } }
/** * Return a scalar {@code Codec} for the given range. * * @param domain the domain of the returned {@code Codec} * @return a new scalar {@code Codec} with the given domain. * @throws NullPointerException if the given {@code domain} is {@code null} */ public static Codec<Double, DoubleGene> ofScalar(final DoubleRange domain) { requireNonNull(domain); return Codec.of( Genotype.of(DoubleChromosome.of(domain)), gt -> gt.getGene().getAllele() ); }
public static void main(final String[] args) { final Problem<int[][], IntegerGene, Integer> problem = Problem.of( Matrix::fitness, Codec.of( Genotype.of(IntegerChromosome.of(IntRange.of(0, 10), 3), 3), gt -> gt.stream() .map(ch -> ch.stream() .mapToInt(IntegerGene::intValue).toArray()) .toArray(int[][]::new) ) ); final Engine<IntegerGene, Integer> engine = Engine.builder(problem).build(); final Genotype<IntegerGene> gt = engine.stream() .limit(Limits.byFixedGeneration(20)) .collect(EvolutionResult.toBestGenotype()); final int[][] best = problem.codec().decode(gt); print(best); }
/** * Returns the fitness value for the given argument. * * @since 4.1 * * @param genotype the argument of the fitness function * @return the fitness value */ public default C fitness(final Genotype<G> genotype) { return fitness(codec().decode(genotype)); }
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()); }
/** * Return a collector which collects the best <em>result</em> (in the native * problem space). * * <pre>{@code * final Problem<ISeq<Point>, EnumGene<Point>, Double> tsm = ...; * final ISeq<Point> route = Engine.builder(tsm) * .optimize(Optimize.MINIMUM).build() * .stream() * .limit(100) * .collect(EvolutionResult.toBestResult(tsm.codec())); * }</pre> * * If the collected {@link EvolutionStream} is empty, the collector returns * <b>{@code null}</b>. * * @since 3.6 * * @param codec the problem decoder * @param <T> the <em>native</em> problem result type * @param <G> the gene type * @param <C> the fitness result type * @return a collector which collects the best result of an evolution stream * @throws NullPointerException if the given {@code codec} is {@code null} */ public static <G extends Gene<?, G>, C extends Comparable<? super C>, T> Collector<EvolutionResult<G, C>, ?, T> toBestResult(final Codec<T, G> codec) { return toBestResult(codec.decoder()); }
@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); } }
/** * Return a scalar {@code Codec} for the given range. * * @param domain the domain of the returned {@code Codec} * @return a new scalar {@code Codec} with the given domain. * @throws NullPointerException if the given {@code domain} is {@code null} */ public static Codec<Long, LongGene> ofScalar(final LongRange domain) { requireNonNull(domain); return Codec.of( Genotype.of(LongChromosome.of(domain)), gt -> gt.getGene().getAllele() ); }
@Test public void variableDoubleSum() { final Problem<int[], IntegerGene, Integer> problem = Problem.of( array -> IntStream.of(array).sum(), Codec.of( Genotype.of(IntegerChromosome.of(0, 100, IntRange.of(10, 100))), gt -> gt.getChromosome().as(IntegerChromosome.class).toArray() ) ); final Engine<IntegerGene, Integer> engine = Engine.builder(problem) .alterers( new Mutator<>(), new SwapMutator<>()) .selector(new TournamentSelector<>()) .minimizing() .build(); final int[] result = problem.codec().decode( engine.stream() .limit(100) .collect(EvolutionResult.toBestGenotype()) ); Assert.assertTrue(result.length < 50, "result length: " + result.length); //System.out.println(result.length); //System.out.println(Arrays.toString(result)); }
@Test public void ofMapping1() { final ISeq<Integer> numbers = ISeq.of(1, 2, 3, 4, 5); final ISeq<String> chars = ISeq.of("A", "B", "C"); final Codec<Map<Integer, String>, EnumGene<Integer>> codec = Codecs.ofMapping(numbers, chars); final Function<Map<Integer, String>, Integer> ff = map -> map.keySet().stream().mapToInt(Integer::intValue).sum(); Engine<EnumGene<Integer>, Integer> engine = Engine.builder(ff, codec) .build(); final Map<Integer, String> best = codec.decode( engine.stream() .limit(100) .collect(EvolutionResult.toBestGenotype()) ); Assert.assertTrue(best.containsKey(3)); Assert.assertTrue(best.containsKey(4)); Assert.assertTrue(best.containsKey(5)); }