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

Java 使用Jenetics创建基因型时的约束,java,genetic-algorithm,jenetics,Java,Genetic Algorithm,Jenetics,我正在试验多目标优化问题(MOP)使用。我创造的一个玩具问题是从一个给定的集合中选择两个子集,最大化它们的总和,因为每个子集都有一个限制。 但是,我想确保这两个子集是互斥的。在创建两条染色体的基因型时,如何设置此约束 我用于解决玩具问题的集合是: private static final ISeq<Integer> SET = ISeq.of( IntStream.rangeClosed( 1, 10 ) .boxed() .colle

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

我用于解决玩具问题的集合是:

private static final ISeq<Integer> SET = ISeq.of( IntStream.rangeClosed( 1, 10 )
            .boxed()
            .collect( Collectors.toList() ) );
Problem<List<ISeq<Integer>>, BitGene, Vec<int[]>>

但我希望两个人都有相互排斥的项目。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())
        )
    );
}
private static final ISeq SET1=IntStream.rangeClosed(1,10)
.boxed()
.collect(ISeq.toISeq());
私有静态最终ISeq SET2=IntStream.rangeClosed(11,20)
.boxed()
.collect(ISeq.toISeq());
公共编解码器{
返回编解码器(
基因型(
bitChrome.of(SET1.length()),
bitChrome.of(SET2.length())
),
gt->ISeq.of(
gt.getChrome(0).as(bitChrome.class).ones()
.mapToObj(SET1)
.collect(ISeq.toISeq()),
gt.getChrome(1).as(bitChrome.class).ones()
.mapToObj(SET2)
.collect(ISeq.toISeq())
)
);
}

有了这两个整数集,您就保证了显著性。

这不是问题的唯一可能编码,因为每个问题都有自己的特点。对于多背包问题,我会选择一个
整合染色体
,而不是
位染色体

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;
        }
    );
}
private static final ISeq ITEMS=IntStream.rangeClosed(1,10)
.boxed()
.collect(ISeq.toISeq());
公共编解码器编解码器(最终整数背包计数){
返回编解码器(
基因型(
0,背包计数,ITEMS.length()
),
gt->{
最终ISeq背包=IntStream.range(0,背包计数)
.mapToObj(i->新建ArrayList())
.collect(ISeq.toISeq());
对于(int i=0;i

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

感谢您的快速响应。所以我认为拥有不同的基因集是产生不同基因集的唯一途径。我会接受这个答案。您还可以建议我需要采取什么样的方法,以便使用
jenetics.ext
模块将多背包问题作为多目标问题来解决吗?这提出了一个类似的问题,我需要用一组不同的物品填充多个背包,这些物品来自给定的有限物品集合,满足最大重量条件。在这种情况下,拥有两个不同的集合是不可行的。这是完美的。我可以轻松地将此方法扩展到其他问题。
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())
        )
    );
}
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;
        }
    );
}