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; }
@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() ); }
@Override public Codec<ISeq<BitGene>, BitGene> codec() { return Codec.of( Genotype.of(BitChromosome.of(_length, _onesProbability)), gt -> gt.getChromosome().toSeq() ); }
@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); } }
@Test public void iterator() { final Chromosome<G> c = factory().newInstance(); final ISeq<G> a = c.toSeq(); int index = 0; for (G gene : c) { Assert.assertEquals(gene, a.get(index)); Assert.assertEquals(gene, c.getGene(index)); ++index; } }
@Test public void length() { final Chromosome<G> c = factory().newInstance(); final ISeq<G> a = c.toSeq(); Assert.assertEquals(c.length(), a.length()); }
@Test public void selectMinimum() { final Function<Genotype<IntegerGene>, Integer> ff = gt -> gt.getChromosome().toSeq().stream() .mapToInt(IntegerGene::intValue) .sum(); Factory<Genotype<IntegerGene>> gtf = Genotype.of(IntegerChromosome.of(0, 100, 10)); final ISeq<Phenotype<IntegerGene, Integer>> population = IntStream.range(0, 50) .mapToObj(i -> Phenotype.of(gtf.newInstance(), 50, ff)) .collect(ISeq.toISeq()); final StochasticUniversalSelector<IntegerGene, Integer> selector = new StochasticUniversalSelector<>(); final ISeq<Phenotype<IntegerGene, Integer>> selection = selector.select(population, 50, Optimize.MINIMUM); }
@Test public void getGene() { final Chromosome<G> c = factory().newInstance(); final ISeq<G> genes = c.toSeq(); Assert.assertEquals(c.getGene(), genes.get(0)); for (int i = 0; i < genes.length(); ++i) { Assert.assertSame(c.getGene(i), genes.get(i)); } }
@Override protected int recombine( final MSeq<Phenotype<G, C>> population, final int[] individuals, final long generation ) { final Random random = RandomRegistry.getRandom(); final Phenotype<G, C> pt1 = population.get(individuals[0]); final Phenotype<G, C> pt2 = population.get(individuals[1]); final Genotype<G> gt1 = pt1.getGenotype(); final Genotype<G> gt2 = pt2.getGenotype(); //Choosing the Chromosome index for crossover. final int cindex = random.nextInt(min(gt1.length(), gt2.length())); final MSeq<Chromosome<G>> c1 = gt1.toSeq().copy(); final ISeq<Chromosome<G>> c2 = gt2.toSeq(); // Calculate the mean value of the gene array. final MSeq<G> mean = mean( c1.get(cindex).toSeq().copy(), c2.get(cindex).toSeq() ); c1.set(cindex, c1.get(cindex).newInstance(mean.toISeq())); population.set( individuals[0], pt1.newInstance(Genotype.of(c1), generation) ); return 1; }
/** * Swaps the genes in the given array, with the mutation probability of this * mutation. */ @Override protected MutatorResult<Chromosome<G>> mutate( final Chromosome<G> chromosome, final double p, final Random random ) { final MutatorResult<Chromosome<G>> result; if (chromosome.length() > 1) { final MSeq<G> genes = chromosome.toSeq().copy(); final int mutations = (int)indexes(random, genes.length(), p) .peek(i -> genes.swap(i, random.nextInt(genes.length()))) .count(); result = MutatorResult.of( chromosome.newInstance(genes.toISeq()), mutations ); } else { result = MutatorResult.of(chromosome); } return result; }
@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)); } } }); }
@Test(invocationCount = 5) public void onesCountLimit() { final Problem<ISeq<BitGene>, BitGene, Integer> problem = Problem.of( genes -> (int)genes.stream().filter(BitGene::getBit).count(), Codec.of( Genotype.of(BitChromosome.of(20, 0.125)), gt -> gt.getChromosome().toSeq() ) ); final Engine<BitGene, Integer> engine = Engine.builder(problem) .build(); final EvolutionResult<BitGene, Integer> result = engine.stream() .limit(Limits.byPopulationConvergence(0.015)) .collect(toBestEvolutionResult()); Assert.assertTrue( result.getTotalGenerations() < 2901, "Gen: " + result.getTotalGenerations() ); }
@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)); } } }); }
@Test(invocationCount = 5) public void onesCountLimit() { final Problem<ISeq<BitGene>, BitGene, Integer> problem = Problem.of( genes -> (int)genes.stream().filter(BitGene::getBit).count(), Codec.of( Genotype.of(BitChromosome.of(20, 0.125)), gt -> gt.getChromosome().toSeq() ) ); final Engine<BitGene, Integer> engine = Engine.builder(problem) .build(); final EvolutionResult<BitGene, Integer> result = engine.stream() .limit(Limits.byFitnessConvergence(5, 10, 0.01)) .collect(EvolutionResult.toBestEvolutionResult()); Assert.assertTrue( result.getTotalGenerations() < 50, "Gen: " + result.getTotalGenerations() ); }