|
| 1 | +package jp.kusumotolab.kgenprog.ga.crossover; |
| 2 | + |
| 3 | +import java.util.Arrays; |
| 4 | +import java.util.Collection; |
| 5 | +import java.util.List; |
| 6 | +import java.util.stream.Collectors; |
| 7 | +import java.util.stream.Stream; |
| 8 | +import jp.kusumotolab.kgenprog.ga.variant.Base; |
| 9 | +import jp.kusumotolab.kgenprog.ga.variant.CascadeCrossoverHistoricalElement; |
| 10 | +import jp.kusumotolab.kgenprog.ga.variant.Gene; |
| 11 | +import jp.kusumotolab.kgenprog.ga.variant.HistoricalElement; |
| 12 | +import jp.kusumotolab.kgenprog.ga.variant.Variant; |
| 13 | +import jp.kusumotolab.kgenprog.ga.variant.VariantStore; |
| 14 | + |
| 15 | +/** |
| 16 | + * 直列的な交叉を行うクラス. |
| 17 | + * |
| 18 | + * @author shinsuke |
| 19 | + */ |
| 20 | +public class CascadeCrossover extends CrossoverAdaptor { |
| 21 | + |
| 22 | + /** |
| 23 | + * @param firstStrategy 1つ目の親を選ぶためのアルゴリズム |
| 24 | + * @param secondStrategy 2つ目の親を選ぶためのアルゴリズム |
| 25 | + */ |
| 26 | + public CascadeCrossover(final FirstVariantSelectionStrategy firstStrategy, |
| 27 | + final SecondVariantSelectionStrategy secondStrategy) { |
| 28 | + super(firstStrategy, secondStrategy, 2); |
| 29 | + } |
| 30 | + |
| 31 | + |
| 32 | + @Override |
| 33 | + protected List<Variant> makeVariants(final List<Variant> variants, final VariantStore store) |
| 34 | + throws CrossoverInfeasibleException { |
| 35 | + final Variant v1 = getFirstVariantSelectionStrategy().exec(variants); |
| 36 | + final Variant v2 = getSecondVariantSelectionStrategy().exec(variants, v1); |
| 37 | + final HistoricalElement histElement = new CascadeCrossoverHistoricalElement(v1, v2); |
| 38 | + |
| 39 | + // create two variants from cascaded genes |
| 40 | + final Gene cascadeGene1 = createCascadeGene(v1, v2); |
| 41 | + final Gene cascadeGene2 = createCascadeGene(v2, v1); // NOSONAR: it's intentional. |
| 42 | + final Variant newVariant1 = store.createVariant(cascadeGene1, histElement); |
| 43 | + final Variant newVariant2 = store.createVariant(cascadeGene2, histElement); |
| 44 | + |
| 45 | + return Arrays.asList(newVariant1, newVariant2); |
| 46 | + } |
| 47 | + |
| 48 | + @Override |
| 49 | + protected List<Variant> filter(final List<Variant> variants) { |
| 50 | + return variants; // no filter necessary |
| 51 | + } |
| 52 | + |
| 53 | + private Gene createCascadeGene(final Variant v1, final Variant v2) { |
| 54 | + final List<Base> cascadeBases = Stream.of(v1, v2) |
| 55 | + .map(Variant::getGene) |
| 56 | + .map(Gene::getBases) |
| 57 | + .flatMap(Collection::stream) |
| 58 | + .distinct() // remove shared genes meaning these two variants have blood relation |
| 59 | + .collect(Collectors.toList()); |
| 60 | + return new Gene(cascadeBases); |
| 61 | + } |
| 62 | + |
| 63 | +} |
0 commit comments