Рекомбинация для создания нового генотипа путем замены хромосом - PullRequest
1 голос
/ 06 ноября 2019

В документации Jenetics указано, что рекомбинация создает новую хромосому путем объединения частей двух (или более) родительских хромосом. Основываясь на этом, библиотека также предоставляет конкретные реализации для различных методов кроссовера. Есть ли какая-либо особенность, которую я могу использовать для рекомбинации двух (или более) генотипов в популяции (т. Е. Обмена хромосом), оставляя гены каждой хромосомы нетронутыми?

Рассмотрим пример, в котором исходная популяция состоит из 2 генотипов, каждый из которых состоит из 2 хромосом. И мне нужно пересечение между двумя индивидуумами так, чтобы обменивались только хромосомы, оставляя гены нетронутыми.

Illustration of the example

Тот же пример в коде показан ниже:

    // Create the initial population
    final List<Genotype<CharacterGene>> initialPopulation = List.of( Genotype.of(
            CharacterChromosome.of( "world" ),
            CharacterChromosome.of( "fuzzy" )
    ), Genotype.of(
            CharacterChromosome.of( "stack" ),
            CharacterChromosome.of( "hello" )
    ) );

    // Configure the Engine
    final Engine<CharacterGene, Vec<int[]>> engine =
    Engine.builder( CrossoverExercise::eval, factory ) //
            .populationSize( 2 ) //
            .offspringFraction( 1 ) //
            .alterers( new CustomWordCrossover() ) //
            .build();

    final Phenotype<CharacterGene, Vec<int[]>> result = engine.stream( initialPopulation ) //
    .limit( 10 ) //
    .collect( EvolutionResult.toBestPhenotype() );

Где класс CustomWordCrossover расширяет интерфейс Alterer для случайного обмена хромосомами между генотипами.

public class CustomWordCrossover implements Alterer<CharacterGene, Vec<int[]>> {

    @Override
    public AltererResult<CharacterGene, Vec<int[]>> alter( final Seq<Phenotype<CharacterGene, Vec<int[]>>> population,
        final long generation ) {

        final ISeq<Phenotype<CharacterGene, Integer>> newPopulation = swapWords( population, generation );
        return AltererResult.of( newPopulation );

    }

    private ISeq<Phenotype<CharacterGene, Integer>> swapWords( final Seq<Phenotype<CharacterGene, Integer>> population,
        final long generation ) {
        final Phenotype<CharacterGene, Integer> p0 = population.get( 0 );
        final Phenotype<CharacterGene, Integer> p1 = population.get( 1 );

        return ISeq.of(
            Phenotype.of( Genotype.of( p0.getGenotype().get( 1 ), p1.getGenotype().get( 0 ) ), generation ),
            Phenotype.of( Genotype.of( p1.getGenotype().get( 1 ), p0.getGenotype().get( 0 ) ), generation )
        );
    }

}

Есть ли лучший подход для достижения этого? Встроенная функция библиотеки возможно? Я ничего не мог найти в документации до сих пор.

1 Ответ

1 голос
/ 06 ноября 2019

Нет встроенной операции пересечения библиотеки для вашего конкретного варианта использования. Причина этого заключается в том, что разные хромосомы в пределах одного генотипа / фенотипа имеют разные ограничения. Это означает, что, как правило, две хромосомы с разными индексами генотипа не являются взаимозаменяемыми.

Genotype<DoubleGene> gt = Genotype.of(
    DoubleChromosome.of(DoubleRange.of(0, 10), 4),
    DoubleChromosome.of(DoubleRange.of(67, 323), 9)
);

В приведенном выше примере две хромосомы имеют разные диапазоны и разные длины. Так что невозможно поменять его, не разрушив кодировку. Ваша конкретная кодировка, с другой стороны, позволяет менять две хромосомы внутри генотипа. Ваша кодировка не будет уничтожена.

Краткий ответ: нет библиотеки для этого конкретного случая. И ваша реализация выглядит хорошо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...