Skip to content

Instantly share code, notes, and snippets.

@jenetics
Created May 9, 2016 18:09
Show Gist options
  • Save jenetics/cb2c2a285a855966ac1de86d34a7b995 to your computer and use it in GitHub Desktop.
Save jenetics/cb2c2a285a855966ac1de86d34a7b995 to your computer and use it in GitHub Desktop.
Example for dynamic Genotype/Chromosome length
import static java.lang.Math.pow;
import static org.jenetics.internal.math.random.indexes;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.stream.IntStream;
import org.jenetics.internal.util.IntRef;
import org.jenetics.AbstractAlterer;
import org.jenetics.Chromosome;
import org.jenetics.DoubleChromosome;
import org.jenetics.DoubleGene;
import org.jenetics.Gene;
import org.jenetics.Genotype;
import org.jenetics.Phenotype;
import org.jenetics.Population;
import org.jenetics.engine.Engine;
import org.jenetics.engine.EvolutionResult;
import org.jenetics.util.Factory;
import org.jenetics.util.ISeq;
import org.jenetics.util.RandomRegistry;
public class DynamicGenotype {
// Explicit Genotype factory instead of Genotype templates.
private static final Factory<Genotype<DoubleGene>> ENCODING = () -> {
final Random random = RandomRegistry.getRandom();
return Genotype.of(
// Vary the chromosome count between 10 and 20.
IntStream.range(0, random.nextInt(10) + 10)
// Vary the chromosome length between 10 and 20.
.mapToObj(i -> DoubleChromosome.of(0, 10, random.nextInt(10) + 10))
.collect(ISeq.toISeq())
);
};
private static double fitness(final Genotype<DoubleGene> gt) {
// Calculate fitness from "dynamic" Genotype.
System.out.println("Gene count: " + gt.getNumberOfGenes());
return 0;
}
// The special mutator also variates the chromosome/genotype length.
private static final class DynamicMutator<
G extends Gene<?, G>,
C extends Comparable<? super C>
>
extends AbstractAlterer<G, C>
{
public DynamicMutator(double probability) {
super(probability);
}
@Override
public int alter(
final Population<G, C> population,
final long generation
) {
final double p = pow(_probability, 1.0/3.0);
final IntRef alterations = new IntRef(0);
indexes(RandomRegistry.getRandom(), population.size(), p).forEach(i -> {
final Phenotype<G, C> pt = population.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);
population.set(i, mpt);
});
return alterations.value;
}
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);
}
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 int mutate(final List<G> genes, final double p) {
final Random random = RandomRegistry.getRandom();
// Add/remove Gene from chromosome.
final double rd = random.nextDouble();
if (rd < 1/3.0) {
genes.remove(0);
} else if (rd < 2/3.0) {
genes.add(genes.get(0).newInstance());
}
return (int)indexes(random, genes.size(), p)
.peek(i -> genes.set(i, genes.get(i).newInstance()))
.count();
}
}
public static void main(final String[] args) {
final Engine<DoubleGene, Double> engine = Engine
.builder(DynamicGenotype::fitness, ENCODING)
.alterers(new DynamicMutator<>(0.25))
.build();
final EvolutionResult<DoubleGene, Double> result = engine.stream()
.limit(20)
.collect(EvolutionResult.toBestEvolutionResult());
System.out.println(result.getBestFitness());
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment