有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java重组通过交换染色体创建新的基因型

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

考虑一个例子,其中初始种群由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. # 1 楼答案

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

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

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

    简短回答:对于这个特定的案例,没有库修改器。您的实现看起来很好