Last active
April 15, 2016 17:29
-
-
Save jenetics/fb9ddcde1e66de2e8787e065de150bd1 to your computer and use it in GitHub Desktop.
The Weasle-program with Jenetics (https://en.wikipedia.org/wiki/Weasel_program)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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