/** * Create a new chromosome from the given genes (given as string). * * @param alleles the character genes. * @return a new {@code CharacterChromosome} with the given parameter * @throws IllegalArgumentException if the genes string is empty. */ public static CharacterChromosome of(final String alleles) { return of(alleles, DEFAULT_CHARACTERS); }
@Override public char charAt(final int index) { return getGene(index).charValue(); }
/** * @throws NullPointerException if the given gene array is {@code null}. */ @Override public CharacterChromosome newInstance(final ISeq<CharacterGene> genes) { return new CharacterChromosome(genes, lengthRange()); }
/** * Create a new, <em>random</em> chromosome. */ @Override public CharacterChromosome newInstance() { return of(_validCharacters, lengthRange()); }
@Test public void crossoverAll1() { final CharSeq chars = CharSeq.of("a-zA-Z"); final ISeq<CharacterGene> g1 = CharacterChromosome.of(chars, 20).toSeq(); final ISeq<CharacterGene> g2 = CharacterChromosome.of(chars, 20).toSeq(); final MultiPointCrossover<CharacterGene, Double> crossover = new MultiPointCrossover<>(2000); final int[] points = new int[g1.length()]; for (int i = 0; i < points.length; ++i) { points[i] = i; } final MSeq<CharacterGene> ms1 = g1.copy(); final MSeq<CharacterGene> ms2 = g2.copy(); crossover.crossover(ms1, ms2); }
@Test(dataProvider = "genes") public void newIllegalCharacterChromosome(final String genes) { final CharSeq characters = new CharSeq("012356789"); CharacterChromosome chromosome = CharacterChromosome.of(genes, characters); Assert.assertFalse(chromosome.isValid(), "Chromosome must not be valid"); Assert.assertEquals(new String(new StringBuilder(chromosome)), genes); }
@Test(invocationCount = 20, successPercentage = 95) public void newInstanceDistribution() { using(new Random(12345), r -> { final CharSeq characters = new CharSeq("0123456789"); final CharacterChromosome chromosome = CharacterChromosome.of(characters, 5000); final Histogram<Long> histogram = Histogram.ofLong(0L, 10L, 10); chromosome.stream() .map(g -> Long.valueOf(g.getAllele().toString())) .forEach(histogram); final double[] expected = dist.uniform(histogram.length()); assertDistribution(histogram, expected); }); }
/** * Returns an char array containing all of the elements in this chromosome * in proper sequence. If the chromosome fits in the specified array, it is * returned therein. Otherwise, a new array is allocated with the length of * this chromosome. * * @since 3.0 * * @param array the array into which the elements of this chromosomes are to * be stored, if it is big enough; otherwise, a new array is * allocated for this purpose. * @return an array containing the elements of this chromosome * @throws NullPointerException if the given {@code array} is {@code null} */ public char[] toArray(final char[] array) { final char[] a = array.length >= length() ? array : new char[length()]; for (int i = length(); --i >= 0;) { a[i] = charAt(i); } return a; }
/** * Create a new chromosome with the {@code validCharacters} char set as * valid characters. * * @since 4.3 * * @param validCharacters the valid characters for this chromosome. * @param lengthRange the allowed length range of the chromosome. * @return a new {@code CharacterChromosome} with the given parameter * @throws NullPointerException if the {@code validCharacters} is * {@code null}. * @throws IllegalArgumentException if the length of the gene sequence is * empty, doesn't match with the allowed length range, the minimum * or maximum of the range is smaller or equal zero or the given * range size is zero. */ public static CharacterChromosome of( final CharSeq validCharacters, final IntRange lengthRange ) { return new CharacterChromosome( CharacterGene.seq(validCharacters, lengthRange), lengthRange ); }
private void writeObject(final ObjectOutputStream out) throws IOException { out.defaultWriteObject(); out.writeInt(length()); out.writeObject(_validCharacters); for (CharacterGene gene : _genes) { out.writeChar(gene.getAllele()); } }
@Test public void crossover() { final ISeq<CharacterGene> g1 = CharacterChromosome.of("1234567890").toSeq(); final ISeq<CharacterGene> g2 = CharacterChromosome.of("abcdefghij").toSeq(); final int rv1 = 12; using(new Random(10), r -> { final UniformCrossover<CharacterGene, Double> crossover = new UniformCrossover<>(0.5, 0.5); MSeq<CharacterGene> g1c = g1.copy(); MSeq<CharacterGene> g2c = g2.copy(); final int changed = crossover.crossover(g1c, g2c); Assert.assertEquals(changed, IntStream.range(0, g2c.length()) .filter(i -> Character.isDigit(g2c.get(i).charValue())) .count() ); }); }
/** * Create a new chromosome from the given genes (given as string). * * @param alleles the character genes. * @param validChars the valid characters. * @return a new {@code CharacterChromosome} with the given parameter * @throws IllegalArgumentException if the genes string is empty. */ public static CharacterChromosome of( final String alleles, final CharSeq validChars ) { final IntRef index = new IntRef(); final Supplier<CharacterGene> geneFactory = () -> CharacterGene.of( alleles.charAt(index.value++), validChars ); final ISeq<CharacterGene> genes = MSeq.<CharacterGene>ofLength(alleles.length()) .fill(geneFactory) .toISeq(); return new CharacterChromosome(genes, IntRange.of(alleles.length())); }
/** * Create a new chromosome with the {@link CharacterGene#DEFAULT_CHARACTERS} * char set as valid characters. * * @param lengthRange the allowed length range of the chromosome. * @return a new {@code CharacterChromosome} with the given parameter * @throws IllegalArgumentException if the {@code length} is smaller than * one. */ public static CharacterChromosome of(final IntRange lengthRange) { return of(DEFAULT_CHARACTERS, lengthRange); }
@Test(dataProvider = "numberOfCrossoverPoints") public void reverseCrossover(final Integer npoints) { for (int i = 1; i < 500; ++i) { final CharSeq chars = CharSeq.of("a-zA-Z"); final ISeq<Character> a = CharacterChromosome.of(chars, i).toSeq() .map(CharacterGene::getAllele); final ISeq<Character> b = CharacterChromosome.of(chars, i).toSeq() .map(CharacterGene::getAllele); final MSeq<Character> ma1 = a.copy(); final MSeq<Character> mb1 = b.copy(); final int[] points = comb.subset( a.length() + 1, min(npoints, a.length() + 1), new Random(1234) ); MultiPointCrossover.crossover(ma1, mb1, points); MultiPointCrossover.crossover(ma1, mb1, points); Assert.assertEquals(ma1, a); Assert.assertEquals(mb1, b); } }
@Override public CharacterChromosome subSequence(final int start, final int end) { return new CharacterChromosome(_genes.subSeq(start, end), lengthRange()); }
/** * Return a {@link Writer} for {@link io.jenetics.CharacterChromosome} * objects. * * @return a chromosome writer */ public static Writer<io.jenetics.CharacterChromosome> writer() { return elem(ROOT_NAME, attr(LENGTH_NAME).map(io.jenetics.CharacterChromosome::length), elem(VALID_ALLELES_NAME, text().map(ch -> ch.getGene().getValidCharacters())), elem(ALLELES_NAME, text().map(io.jenetics.CharacterChromosome::toString)) ); }
/** * Create a new chromosome with the {@link CharacterGene#DEFAULT_CHARACTERS} * char set as valid characters. * * @param length the {@code length} of the new chromosome. * @return a new {@code CharacterChromosome} with the given parameter * @throws IllegalArgumentException if the {@code length} is smaller than * one. */ public static CharacterChromosome of(final int length) { return of(DEFAULT_CHARACTERS, length); }
@Test public void crossoverChanges() { final ISeq<CharacterGene> g1 = CharacterChromosome.of("1234567890").toSeq(); final ISeq<CharacterGene> g2 = CharacterChromosome.of("abcdefghij").toSeq(); final int rv1 = 12; using(new Random(10), r -> { final UniformCrossover<CharacterGene, Double> crossover = new UniformCrossover<>(0.5, 0.5); final DoubleMomentStatistics statistics = new DoubleMomentStatistics(); for (int j = 0; j < 1000; ++j) { MSeq<CharacterGene> g1c = g1.copy(); MSeq<CharacterGene> g2c = g2.copy(); final int changed = crossover.crossover(g1c, g2c); Assert.assertEquals(changed, IntStream.range(0, g2c.length()) .filter(i -> Character.isDigit(g2c.get(i).charValue())) .count() ); statistics.accept(changed); } Assert.assertEquals(statistics.getMean(), 5.0, 0.0001); }); }
@Override protected Factory<Chromosome<CharacterGene>> factory() { return () -> CharacterChromosome.of(500); }