Skip to content

Instantly share code, notes, and snippets.

@jenetics
Last active April 15, 2016 17:29
Show Gist options
  • Save jenetics/fb9ddcde1e66de2e8787e065de150bd1 to your computer and use it in GitHub Desktop.
Save jenetics/fb9ddcde1e66de2e8787e065de150bd1 to your computer and use it in GitHub Desktop.
The Weasle-program with Jenetics (https://en.wikipedia.org/wiki/Weasel_program)
class WeaselSelector<
G extends Gene<?, G>,
C extends Comparable<? super C>
>
implements Selector<G, C>
{
@Override
public Population<G, C> select(
final Population<G, C> population,
final int count,
final Optimize opt
) {
requireNonNull(population, "Population");
requireNonNull(opt, "Optimization");
if (count < 0) {
throw new IllegalArgumentException(format(
"Selection count must be greater or equal then zero, but was %s",
count
));
}
final MinMax<Phenotype<G, C>> minMax = population.stream()
.collect(MinMax.toMinMax(opt.ascending()));
return new Population<G, C>(count).fill(minMax::getMax, count);
}
}
class WeaselMutator<
G extends Gene<?, G>,
C extends Comparable<? super C>
>
extends Mutator<G, C>
{
public WeaselMutator(final double probability) {
super(probability);
}
public WeaselMutator() {
this(0.05);
}
@Override
public int alter(final Population<G, C> population, final long generation) {
final IntRef alterations = new IntRef(0);
for (int i = 0; i < population.size(); ++i) {
final Phenotype<G, C> pt = population.get(i);
final Genotype<G> gt = pt.getGenotype();
final Genotype<G> mgt = mutate(gt, 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 IntRef alterations
) {
final MSeq<Chromosome<G>> chromosomes = genotype.toSeq().copy();
alterations.value += IntStream.range(0, chromosomes.size())
.map(i -> mutate(chromosomes, i))
.sum();
return Genotype.of(chromosomes);
}
private int mutate(final MSeq<Chromosome<G>> c, final int index) {
final Chromosome<G> chromosome = c.get(index);
final MSeq<G> genes = chromosome.toSeq().copy();
final int mutations = mutate(genes, _probability);
if (mutations > 0) {
c.set(index, chromosome.newInstance(genes.toISeq()));
}
return mutations;
}
}
// See: https://en.wikipedia.org/wiki/Weasel_program
public class WeaselProgram {
private static final String TARGET_STRING = "methinks it is like a weasel";
private static Integer evaluate(final Genotype<CharacterGene> gt) {
final CharSequence source = (CharSequence)gt.getChromosome();
return IntStream.range(0, TARGET_STRING.length())
.map(i -> source.charAt(i) == TARGET_STRING.charAt(i) ? 1 : 0)
.sum();
}
public static void main(String[] args) throws Exception {
final CharSeq chars = CharSeq.of("a-z ");
final Factory<Genotype<CharacterGene>> gtf = Genotype.of(
new CharacterChromosome(chars, TARGET_STRING.length())
);
final Engine<CharacterGene, Integer> engine = Engine
.builder(WeaselProgram::evaluate, gtf)
.populationSize(200)
.selector(new WeaselSelector<>())
.offspringFraction(1)
.alterers(new WeaselMutator<>(0.05))
.build();
final Phenotype<CharacterGene, Integer> result = engine.stream()
.limit(50)
.peek(r -> System.out.println(r.getBestPhenotype()))
.collect(toBestPhenotype());
System.out.println(result);
}
}
/*
Output:
[mjtyx rj ibqqnxgatyrhsdkabex] --> 6
[mjtyx rj ibqqnxgakyrhsdeabex] --> 8
[mjtye rj ibqqnxgakyrhsdeasex] --> 9
[metye rs ibqqnxggkgrhsyeasex] --> 11
[metye rs ibqqsxggkgrhsaeasex] --> 12
[metye rs ibqqsxggkgrhsaeasel] --> 13
[metye rs ibdisxggkgrhsaeasel] --> 14
[metye rs ibdisxggkg hsaeasel] --> 15
[metye hs ibdiszggkg esweasel] --> 16
[metye hs ibdiszggkg asweasel] --> 17
[metye hs ibdiszggkg asweasel] --> 17
[metye hs ib iszggkg asweasel] --> 18
[metye hs ib iszggkg asweasel] --> 18
[metye hs ib iszggkg asweasel] --> 18
[metye hs ib iszggkg a weasel] --> 19
[metye hs ib iszggkg a weasel] --> 19
[metye hs ib iszgikg a weasel] --> 20
[metye hs ib iszgikg a weasel] --> 20
[metye hs ib iszgikg a weasel] --> 20
[metyenhs ib iszgikg a weasel] --> 21
[metyenhs ib is gikg a weasel] --> 22
[methenhs ib is gikg a weasel] --> 23
[methenhs ib is gike a weasel] --> 24
[methenhs it is gike a weasel] --> 25
[methenhs it is gike a weasel] --> 25
[methenhs it is gike a weasel] --> 25
[methenhs it is gike a weasel] --> 25
[methenhs it is gike a weasel] --> 25
[methenhs it is gike a weasel] --> 25
[methenhs it is like a weasel] --> 26
[methinhs it is like a weasel] --> 27
[methinhs it is like a weasel] --> 27
[methinhs it is like a weasel] --> 27
[methinhs it is like a weasel] --> 27
[methinhs it is like a weasel] --> 27
[methinhs it is like a weasel] --> 27
[methinhs it is like a weasel] --> 27
[methinhs it is like a weasel] --> 27
[methinhs it is like a weasel] --> 27
[methinhs it is like a weasel] --> 27
[methinhs it is like a weasel] --> 27
[methinhs it is like a weasel] --> 27
[methinks it is like a weasel] --> 28
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment