Ограничения при создании генотипа с использованием Jenetics - PullRequest
1 голос
/ 18 октября 2019

Я экспериментирую с проблемой многоцелевой оптимизации (MOP), используя Jenetics . Игрушечная проблема, которую я создал, состоит в том, чтобы выбрать два подмножества из данного набора, максимизируя их общую сумму, учитывая, что у каждого подмножества есть предел. Однако я хочу убедиться, что эти два подмножества являются взаимоисключающими. Как я могу установить это ограничение при создании генотипа двух хромосом?

Набор, который я использую для задачи с игрушкой:

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.

Пример вывода, который я сейчас получаю:

[[4,5], [4]]

Но я ожидаю, что у обоих людей будут взаимоисключающие предметы. Как этого можно добиться с помощью Jenetics?

Ответы [ 2 ]

1 голос
/ 18 октября 2019

Это не единственно возможное кодирование вашей проблемы, поскольку каждая проблема имеет свои особенности. Для проблемы с несколькими ранцами я бы выбрал 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(). Если индекс выходит за допустимый диапазон, элемент пропускается. Эта кодировка гарантирует четкое разделение элементов.

1 голос
/ 18 октября 2019

Если вам нужен отдельный набор генов, вам нужно определить два различных набора.

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())
        )
    );
}

С двумя целочисленными наборами у вас будет гарантированная отличительность.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...