@Override public AltererResult<G, C> alter( final Seq<Phenotype<G, C>> population, final long generation ) { AltererResult<G, C> result = AltererResult.of(population.asISeq()); for (Alterer<G, C> alterer : _alterers) { final AltererResult<G, C> as = alterer.alter( result.getPopulation(), generation ); result = AltererResult.of( as.getPopulation(), as.getAlterations() + result.getAlterations() ); } return result; }
/** * Return a new alter result for the given arguments. * * @param population the altered population * @param <G> the gene type * @param <C> the result type * @return a new alterer for the given arguments * @throws NullPointerException if the given population is {@code null} */ public static <G extends Gene<?, G>, C extends Comparable<? super C>> AltererResult<G, C> of(final ISeq<Phenotype<G, C>> population) { return new AltererResult<>(population, 0); }
/** * Combine the given alterers. * * @param <G> the gene type * @param <C> the fitness function result type * @param alterers the alterers to combine. * @return a new alterer which consists of the given one * @throws NullPointerException if one of the alterers is {@code null}. */ @SafeVarargs public static <G extends Gene<?, G>, C extends Comparable<? super C>> Alterer<G, C> of(final Alterer<G, C>... alterers) { return alterers.length == 0 ? (p, g) -> AltererResult.of(p.asISeq()) : alterers.length == 1 ? alterers[0] : new CompositeAlterer<>(ISeq.of(alterers)); }
@Test(dataProvider = "alterCountParameters") public void alterCount( final Integer ngenes, final Integer nchromosomes, final Integer npopulation ) { final ISeq<Phenotype<DoubleGene, Double>> p1 = newDoubleGenePopulation(ngenes, nchromosomes, npopulation); final Alterer<DoubleGene, Double> mutator = newAlterer(0.01); final AltererResult<DoubleGene, Double> result = mutator.alter(p1, 1); int mutations = result.getAlterations(); int difference = diff(p1, result.getPopulation()); Assert.assertEquals( mutations, difference, String.format("diff=%s, mutations=%s", difference, mutations) ); }
@Override public AltererResult<G, C> alter( final Seq<Phenotype<G, C>> population, final long generation ) { final AltererResult<G, C> result = _adoptee.alter(population, generation); final MSeq<Phenotype<G, C>> pop = MSeq.of(population); for (int i = 0, n = pop.size(); i < n; ++i) { if (!pop.get(i).isValid()) { pop.set(i, repair(pop.get(i))); } } return AltererResult.of(pop.toISeq(), result.getAlterations()); }
@Test(invocationCount = 10) public void prune() { final MathTreePruneAlterer<ProgramGene<Double>, Double> alterer = new MathTreePruneAlterer<>(1); final Genotype<ProgramGene<Double>> gt = Genotype.of( ProgramChromosome.of(10, OPERATIONS, TERMINALS) ); final Phenotype<ProgramGene<Double>, Double> pt = Phenotype.of(gt, 1, a -> 1.0); final AltererResult<ProgramGene<Double>, Double> result = alterer.alter(Seq.of(pt), 1); final ProgramGene<Double> program = result .getPopulation().get(0) .getGenotype() .getGene(); final MathExpr exp1 = new MathExpr(gt.getGene()).simplify(); final MathExpr exp2 = new MathExpr(program); Assert.assertEquals(exp2, exp1); }
@Override @Test(dataProvider = "alterCountParameters") public void alterCount( final Integer ngenes, final Integer nchromosomes, final Integer npopulation ) { final ISeq<Phenotype<DoubleGene, Double>> p1 = newDoubleGenePopulation(ngenes, nchromosomes, npopulation); final MSeq<Phenotype<DoubleGene, Double>> p2 = p1.copy(); Assert.assertEquals(p2, p1); final Alterer<DoubleGene, Double> mutator = newAlterer(0.01); final int alterations = mutator.alter(p2, 1).getAlterations(); //final int diff = diff(p1, p2); if (ngenes == 1) { Assert.assertEquals(alterations, 0); } else { //Assert.assertTrue(alterations >= diff/2, String.format("%d >= %d", alterations, diff/2)); //Assert.assertTrue(alterations <= 2*diff, String.format("%d < %d", alterations, 2*diff)); } }
@Override public AltererResult<G, C> alter(final Seq<Phenotype<G, C>> population, final long generation) { final Random random = RandomRegistry.getRandom(); final Seq<MutatorResult<Phenotype<G, C>>> result = population .map(pt -> mutate(pt, generation, _probability, random)); return AltererResult.of( result.map(MutatorResult::getResult).asISeq(), result.stream().mapToInt(MutatorResult::getMutations).sum() ); }
@Test(dataProvider = "alterCountParameters") public void alterCount( final Integer ngenes, final Integer nchromosomes, final Integer npopulation ) { final ISeq<Phenotype<DoubleGene, Double>> p1 = population(ngenes, nchromosomes, npopulation); final Alterer<DoubleGene, Double> mutator = newAlterer(0.01); final AltererResult<DoubleGene, Double> result = mutator.alter(p1, 1); Assert.assertEquals( result.getAlterations(), diff(p1, result.getPopulation()) ); }
@Test public void populationRecombine() { RandomRegistry.using(new Random(123), r -> { ISeq<Phenotype<DoubleGene, Double>> pop = newDoubleGenePopulation(5, 1, 2); final MSeq<Phenotype<DoubleGene, Double>> copy = pop.copy(); final IntermediateCrossover<DoubleGene, Double> recombinator = new IntermediateCrossover<>(1); pop = recombinator.alter(pop, 10).getPopulation(); for (int i = 0; i < pop.size(); ++i) { final Seq<DoubleGene> genes = pop.get(i) .getGenotype() .getChromosome() .toSeq(); final Seq<DoubleGene> genesCopy = copy.get(i) .getGenotype() .getChromosome() .toSeq(); for (int j = 0; j < genes.length(); ++j) { Assert.assertNotEquals(genes.get(j), genesCopy.get(i)); } } }); }
final long alterations = crossover .alter(population, 1) .getAlterations(); histogram.accept(alterations); variance.accept(alterations);
@Override public final AltererResult<G, C> alter( final Seq<Phenotype<G, C>> population, final long generation ) { final AltererResult<G, C> result; if (population.size() >= 2) { final Random random = RandomRegistry.getRandom(); final int order = Math.min(_order, population.size()); // Selection of the individuals for recombination. final IntFunction<int[]> individuals = i -> { final int[] ind = subset(population.size(), order, random); ind[0] = i; return ind; }; final MSeq<Phenotype<G, C>> pop = MSeq.of(population); final int count = indexes(random, population.size(), _probability) .mapToObj(individuals) .mapToInt(i -> recombine(pop, i, generation)) .sum(); result = AltererResult.of(pop.toISeq(), count); } else { result = AltererResult.of(population.asISeq()); } return result; }
filter(pop.result.getPopulation(), start.getGeneration()), _clock ); killCount, invalidCount, alteredOffspring.join().result.getAlterations()
@Test public void populationRecombine() { RandomRegistry.using(new Random(123), r -> { ISeq<Phenotype<DoubleGene, Double>> pop = newDoubleGenePopulation(5, 1, 2); final MSeq<Phenotype<DoubleGene, Double>> copy = pop.copy(); final LineCrossover<DoubleGene, Double> recombinator = new LineCrossover<>(1); pop = recombinator.alter(pop, 10).getPopulation(); for (int i = 0; i < pop.size(); ++i) { final Seq<DoubleGene> genes = pop.get(i) .getGenotype() .getChromosome() .toSeq(); final Seq<DoubleGene> genesCopy = copy.get(i) .getGenotype() .getChromosome() .toSeq(); for (int j = 0; j < genes.length(); ++j) { Assert.assertNotEquals(genes.get(j), genesCopy.get(i)); } } }); }
final long alterations = crossover .alter(population, 1) .getAlterations(); histogram.accept(alterations); variance.accept(alterations);
/** * Return a new alter result for the given arguments. * * @param population the altered population * @param alterations the number of altered individuals * @param <G> the gene type * @param <C> the result type * @return a new alterer for the given arguments * @throws NullPointerException if the given population is {@code null} * @throws IllegalArgumentException if the given {@code alterations} is * negative */ public static <G extends Gene<?, G>, C extends Comparable<? super C>> AltererResult<G, C> of( final ISeq<Phenotype<G, C>> population, final int alterations ) { return new AltererResult<>(population, alterations); }
/** * Concrete implementation of the alter method. It uses the following * mutation methods: {@link #mutate(Phenotype, long, double, Random)}, * {@link #mutate(Genotype, double, Random)}, * {@link #mutate(Chromosome, double, Random)}, {@link #mutate(Gene, Random)}, * in this specific order. * * @see #mutate(Phenotype, long, double, Random) * @see #mutate(Genotype, double, Random) * @see #mutate(Chromosome, double, Random) * @see #mutate(Gene, Random) */ @Override public AltererResult<G, C> alter( final Seq<Phenotype<G, C>> population, final long generation ) { assert population != null : "Not null is guaranteed from base class."; final Random random = RandomRegistry.getRandom(); final double p = pow(_probability, 1.0/3.0); final int P = probability.toInt(p); final Seq<MutatorResult<Phenotype<G, C>>> result = population .map(pt -> random.nextInt() < P ? mutate(pt, generation, p, random) : MutatorResult.of(pt)); return AltererResult.of( result.map(MutatorResult::getResult).asISeq(), result.stream().mapToInt(MutatorResult::getMutations).sum() ); }
@Test(dataProvider = "alterProbabilityParameters", groups = {"statistics"}) public void alterProbability( final Integer ngenes, final Integer nchromosomes, final Integer npopulation, final Double p ) { final ISeq<Phenotype<EnumGene<Double>, Double>> population = newPermutationDoubleGenePopulation(ngenes, nchromosomes, npopulation); // The mutator to test. final PartiallyMatchedCrossover<Double, Double> crossover = new PartiallyMatchedCrossover<>(p); final long nallgenes = ngenes*nchromosomes*npopulation; final long N = 100; final double mean = crossover.getOrder()*npopulation*p; final long min = 0; final long max = nallgenes; final Range<Long> domain = new Range<>(min, max); final Histogram<Long> histogram = Histogram.ofLong(min, max, 10); final LongMomentStatistics variance = new LongMomentStatistics(); for (int i = 0; i < N; ++i) { final long alterations = crossover .alter(population, 1) .getAlterations(); histogram.accept(alterations); variance.accept(alterations); } // Normal distribution as approximation for binomial distribution. // TODO: Implement test //assertDistribution(histogram, new NormalDistribution<>(domain, mean, variance.getVariance())); }
@Override public AltererResult<G, C> alter( final Seq<Phenotype<G, C>> population, final long generation ) { final double p = pow(_probability, 1.0/3.0); final IntRef alterations = new IntRef(0); final MSeq<Phenotype<G, C>> pop = MSeq.of(population); indexes(RandomRegistry.getRandom(), pop.size(), p).forEach(i -> { final Phenotype<G, C> pt = pop.get(i); final Genotype<G> gt = pt.getGenotype(); final Genotype<G> mgt = mutate(gt, p, alterations); final Phenotype<G, C> mpt = pt.newInstance(mgt, generation); pop.set(i, mpt); }); return AltererResult.of(pop.toISeq(), alterations.value); }
final long alterations = mutator .alter(population.copy(), 1) .getAlterations();