private static Integer count(final Genotype<BitGene> gt) { return gt.getChromosome() .as(BitChromosome.class) .bitCount(); }
static <G extends NumericGene<?, G>> ISeq<DoubleMoments> statistics(final Seq<? extends Phenotype<G, ?>> population) { final Map<Long, DoubleMomentStatistics> statistics = new HashMap<>(); for (Phenotype<G, ?> pt : population) { final Genotype<G> gt = pt.getGenotype(); for (int i = 0; i < gt.length(); ++i) { final Chromosome<G> ch = gt.getChromosome(i); for (int j = 0; j < ch.length(); ++j) { statistics .computeIfAbsent(((long)i << 32) | (j & 0xffffffffL), k -> new DoubleMomentStatistics()) .accept(ch.getGene(j).doubleValue()); } } } return statistics.values().stream() .map(DoubleMomentStatistics::toDoubleMoments) .collect(ISeq.toISeq()); }
@Override protected MutatorResult<Chromosome<PolygonGene>> mutate( final Chromosome<PolygonGene> chromosome, final double p, final Random random ) { return MutatorResult.of( chromosome.newInstance(chromosome.toSeq().map(this::mutate)), chromosome.length() ); }
private int mutate(final List<Chromosome<G>> c, final int i, final double p) { final Chromosome<G> chromosome = c.get(i); final List<G> genes = new ArrayList<>(chromosome.toSeq().asList()); final int mutations = mutate(genes, p); if (mutations > 0) { c.set(i, chromosome.newInstance(ISeq.of(genes))); } return mutations; }
private MutatorResult<Chromosome<G>> mutate(final Chromosome<G> chromosome) { final TreeNode<A> tree = TreeNode.ofTree(chromosome.getGene()); mutate(tree); final FlatTreeNode<A> flat = FlatTreeNode.of(tree); final ISeq<G> genes = flat.map(t -> gene(chromosome.getGene(), t)); return MutatorResult.of(chromosome.newInstance(genes), 1); }
/** * Return the first gene of this chromosome. Each chromosome must contain * at least one gene. * * @return the first gene of this chromosome. */ public default G getGene() { return getGene(0); }
/** * Returns a sequential {@code Stream} of genes with this chromosome as * its source. * * @since 3.3 * * @return a sequential {@code Stream} of genes */ public default Stream<G> stream() { return IntStream.range(0, length()).mapToObj(this::getGene); }
/** * Mutates the given chromosome. * * @see #mutate(Gene, Random) * * @param chromosome the chromosome to mutate * @param p the mutation probability for the underlying genetic objects * @param random the random engine used for the genotype mutation * @return the mutation result */ protected MutatorResult<Chromosome<G>> mutate( final Chromosome<G> chromosome, final double p, final Random random ) { final int P = probability.toInt(p); final ISeq<MutatorResult<G>> result = chromosome.stream() .map(gene -> random.nextInt() < P ? MutatorResult.of(mutate(gene, random), 1) : MutatorResult.of(gene)) .collect(ISeq.toISeq()); return MutatorResult.of( chromosome.newInstance(result.map(MutatorResult::getResult)), result.stream().mapToInt(MutatorResult::getMutations).sum() ); }
@Override public Codec<ISeq<Rect>, AnyGene<Rect>> codec() { return Codec.of( Genotype.of(AnyChromosome.of( () -> Rect.newInstance(_outer), a -> true, a -> true, MAX_RECT_COUNT )), gt -> gt.getChromosome().stream() .map(AnyGene::getAllele) .filter(r -> r != Rect.EMPTY) .collect(ISeq.toISeq()) ); }
@Override public Codec<ISeq<BitGene>, BitGene> codec() { return Codec.of( Genotype.of(BitChromosome.of(_length, _onesProbability)), gt -> gt.getChromosome().toSeq() ); }
private Genotype<G> mutate( final Genotype<G> genotype, final double p, final IntRef alterations ) { final List<Chromosome<G>> chromosomes = new ArrayList<>(genotype.toSeq().asList()); // Add/remove Chromosome to Genotype. final Random random = RandomRegistry.getRandom(); final double rd = random.nextDouble(); if (rd < 1/3.0) { chromosomes.remove(0); } else if (rd < 2/3.0) { chromosomes.add(chromosomes.get(0).newInstance()); } alterations.value += indexes(RandomRegistry.getRandom(), chromosomes.size(), p) .map(i -> mutate(chromosomes, i, p)) .sum(); return Genotype.of(chromosomes); }
@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 public void newInstanceFromArray() { for (int i = 0; i < 100; ++i) { final Chromosome<G> c1 = factory().newInstance(); final ISeq<G> genes = c1.toSeq(); final Chromosome<G> c2 = c1.newInstance(genes); Assert.assertEquals(c2, c1); Assert.assertEquals(c1, c2); } }
private <A> void crossover( final MSeq<Chromosome<G>> c1, final MSeq<Chromosome<G>> c2, final int index ) { @SuppressWarnings("unchecked") final TreeNode<A> tree1 = (TreeNode<A>)TreeNode.ofTree(c1.get(index).getGene()); @SuppressWarnings("unchecked") final TreeNode<A> tree2 = (TreeNode<A>)TreeNode.ofTree(c2.get(index).getGene()); crossover(tree1, tree2); final FlatTreeNode<A> flat1 = FlatTreeNode.of(tree1); final FlatTreeNode<A> flat2 = FlatTreeNode.of(tree2); @SuppressWarnings("unchecked") final TreeGene<A, ?> template = (TreeGene<A, ?>)c1.get(0).getGene(); final ISeq<G> genes1 = flat1.map(tree -> gene(template, tree)); final ISeq<G> genes2 = flat2.map(tree -> gene(template, tree)); c1.set(index, c1.get(index).newInstance(genes1)); c2.set(index, c2.get(index).newInstance(genes2)); }
private static int ngenes(final Seq<? extends Chromosome<?>> chromosomes) { int count = 0; for (int i = 0, n = chromosomes.length(); i < n; ++i) { count += chromosomes.get(i).length(); } return count; }
/** * Create a permutation {@code Codec} of integer in the range * {@code [0, length)}. * * @param length the number of permutation elements * @return a permutation {@code Codec} of integers * @throws IllegalArgumentException if the {@code length} is smaller than * one. */ public static Codec<int[], EnumGene<Integer>> ofPermutation(final int length) { require.positive(length); return Codec.of( Genotype.of(PermutationChromosome.ofInteger(length)), gt -> gt.getChromosome().stream() .mapToInt(EnumGene::getAllele) .toArray() ); }