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 )
);
}
}
是否有更好的方法来实现这一目标?内置库函数?到目前为止,我在文档中找不到任何内容。
对于您的特定用例,没有内置库交叉操作。其原因是,一个基因型/表型内的不同染色体被认为具有不同的限制。这意味着,通常,具有不同基因型指数的两条染色体是不可互换的。
Genotype<DoubleGene> gt = Genotype.of(
DoubleChromosome.of(DoubleRange.of(0, 10), 4),
DoubleChromosome.of(DoubleRange.of(67, 323), 9)
);
在上面的示例中,两个染色体具有不同的范围和不同的长度。因此,在不破坏编码的情况下就不可能交换它。另一方面,您的特定编码允许交换一个基因型中的两个染色体。您的编码不会被破坏。
简短回答:在这种情况下,没有库修改器。而且您的实现看起来不错。