В документации Jenetics указано, что рекомбинация создает новую хромосому путем объединения частей двух (или более) родительских хромосом. Основываясь на этом, библиотека также предоставляет конкретные реализации для различных методов кроссовера. Есть ли какая-либо особенность, которую я могу использовать для рекомбинации двух (или более) генотипов в популяции (т. Е. Обмена хромосом), оставляя гены каждой хромосомы нетронутыми?
Рассмотрим пример, в котором исходная популяция состоит из 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 )
);
}
}
Есть ли лучший подход для достижения этого? Встроенная функция библиотеки возможно? Я ничего не мог найти в документации до сих пор.