繁体   English   中英

使用 Jenetics 创建基因型时的约束

[英]Constraints when creating a Genotype using Jenetics

我正在使用Jenetics试验多目标优化问题 (MOP)。 我创建的一个玩具问题是 select 来自给定集合的两个子集,最大化它们的总和,因为每个子集都有一个限制。 但是我想确保这两个子集是互斥的。 在创建两条染色体的基因型时如何设置此约束?

我用来解决玩具问题的套装是:

private static final ISeq<Integer> SET = ISeq.of( IntStream.rangeClosed( 1, 10 )
            .boxed()
            .collect( Collectors.toList() ) );

我的问题的签名是:

Problem<List<ISeq<Integer>>, BitGene, Vec<int[]>>

编解码器是:

@Override public Codec<List<ISeq<Integer>>, BitGene> codec() {
        Objects.requireNonNull( SET );
        final Genotype<BitGene> g =
                Genotype.of( BitChromosome.of( SET.length() ), BitChromosome.of( SET.length() ) );
        return Codec.of(
                g,
                gc -> gc.stream().map( z -> z.as( BitChromosome.class ).ones().mapToObj( SET )
                        .collect( ISeq.toISeq() ) ).collect( Collectors.toList() )
        );
    }

我为第一个子集分配了 9 个限制,第二个子集分配了 4 个限制。

我期望两个具有互斥基因的染色体的初始种群,这样表型最终将产生没有从SET复制项目的个体。

我目前得到的一个示例 output 是:

[[4,5], [4]]

但我希望两个人都有相互排斥的物品。 Jenetics 如何做到这一点?

如果你想要一组不同的基因,你必须定义两个不同的组。

private static final ISeq<Integer> SET1 = IntStream.rangeClosed(1, 10)
    .boxed()
    .collect(ISeq.toISeq());

private static final ISeq<Integer> SET2 = IntStream.rangeClosed(11, 20)
    .boxed()
    .collect(ISeq.toISeq());


public Codec<ISeq<ISeq<Integer>>, BitGene> codec() {
    return Codec.of(
        Genotype.of(
            BitChromosome.of(SET1.length()),
            BitChromosome.of(SET2.length())
        ),
        gt -> ISeq.of(
            gt.getChromosome(0).as(BitChromosome.class).ones()
                .mapToObj(SET1)
                .collect(ISeq.toISeq()),
            gt.getChromosome(1).as(BitChromosome.class).ones()
                .mapToObj(SET2)
                .collect(ISeq.toISeq())
        )
    );
}

使用两套 integer 套装,您将保证与众不同。

这不是您问题的唯一可能编码,因为每个问题都有自己的特征。 对于多背包问题,我会选择IntegerChromosome而不是BitChromosomes

private static final ISeq<Integer> ITEMS = IntStream.rangeClosed(1, 10)
    .boxed()
    .collect(ISeq.toISeq());

public Codec<ISeq<List<Integer>>, IntegerGene> codec(final int knapsackCount) {
    return Codec.of(
        Genotype.of(IntegerChromosome.of(
            0, knapsackCount, ITEMS.length())
        ),
        gt -> {
            final ISeq<List<Integer>> knapsacks = IntStream.range(0, knapsackCount)
                .mapToObj(i -> new ArrayList<Integer>())
                .collect(ISeq.toISeq());

            for (int i = 0; i < ITEMS.length(); ++i) {
                final IntegerGene gene = gt.get(0, i);
                if (gene.intValue() < knapsackCount) {
                    knapsacks.get(gene.intValue()).add(ITEMS.get(i));
                }
            }

            return knapsacks;
        }
    );
}

上面给出的编解码器选择了一个IntegerChromoses ,其长度为背包项目数。 它的基因范围将大于背包的数量。 物品i将被放入带有IntegerChromosome.get(0, i).intValue()染色体索引的背包。 如果索引超出有效范围,则跳过该项目。 这种编码将保证项目的明确划分。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM