【问题标题】:Recombination to create a new genotype by swapping chromosomes通过交换染色体进行重组以产生新的基因型
【发布时间】:2020-03-02 19:31:59
【问题描述】:

Jenetics documentation 指定重组通过组合两个(或更多)亲本染色体的一部分来创建一个新染色体。基于此,该库还提供了各种交叉技术的具体实现。是否有一个开箱即用的功能,我可以使用它来重组种群中的两个(或更多)基因型(即交换染色体),而不影响每个染色体的基因?

考虑一个示例,其中初始群体由 2 个基因型组成,每个基因型由 2 条染色体组成。而且我需要两个个体之间的交叉,这样只有染色体被交换,而基因完好无损。

代码中的相同示例如下所示:

    // 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 )
        );
    }

}

有没有更好的方法来实现这一点?也许是内置库函数?到目前为止,我在文档中找不到任何内容。

【问题讨论】:

    标签: java genetic-algorithm jenetics


    【解决方案1】:

    没有针对您的特定用例的内置库交叉操作。其原因是,一种基因型/表型内的不同染色体被认为具有不同的约束条件。这意味着,一般来说,具有不同基因型索引的两条染色体是不可互换的。

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

    在上面的例子中,两条染色体有不同的范围和不同的长度。所以不可能在不破坏编码的情况下交换它。 另一方面,您的特定编码允许在一个基因型中交换两条染色体。您的编码不会被破坏。

    简短回答:没有针对这种特定情况的库更改器。而且你的实现看起来不错。

    【讨论】:

    • 感谢您的澄清。如果我理解正确,应该可以从两个不同的基因型中交换具有相同索引的两条染色体,因为这两种基因型具有相同的编码。例如,从您的代码 sn-p(例如 gt1gt2)创建两个基因型,应该可以在 gt1 的索引 0 和 gt2 的索引 0 处交换染色体。但我猜这必须通过实现Alterer 接口来实现?
    • 对,交换两条具有相同 GT 索引的染色体总是安全的。但目前库中没有此功能的更改器实现。
    猜你喜欢
    • 2013-11-11
    • 2016-11-06
    • 1970-01-01
    • 1970-01-01
    • 2020-03-20
    • 2019-12-16
    • 2013-02-15
    • 1970-01-01
    • 2016-08-05
    相关资源
    最近更新 更多