I would like to implement a multi-objective knapsack problem with two knapsacks in Jenetics, but I struggle with some typing issues. I had a look at the DTLZ1 problem from the Jenetics manual—which is to my knowledge the only MOO example available—and mapped it to the Problem class:
public class DTLZ1 implements Problem<double[], DoubleGene, Vec<double[]>> {
// Constants...
public static void main(String[] args) {
// Engine setup and evolution stream execution...
}
@Override
public Function<double[], Vec<double[]>> fitness() {
// Original fitness function...
}
@Override
public Codec<double[], DoubleGene> codec() {
// Original codec...
}
}
I have previously implemented a single-objective knapsack problem in Scala using the following type signature (converted to Java):
Problem<ISeq<BitGene>, BitGene, Integer>
Where:
<ISeq<BitGene>: a knapsack as a (immutable) sequence of bits.BitGene: the gene type of the evolution engine.Integer: the fitness of the knapsack, i.e., its profit.
Using two knapsacks, I thought about something like (based on the DTLZ1 example):
Problem<ISeq<BitGene>[], BitGene, Vec<int[]>>
Where:
ISeq<BitGene>[]: multiple knapsacks as (immutable) sequences of bits, wrapped in an array.BitGene: the gene type of the evolution engine (same as above).int[]: the fitness of the knapsacks, i.e., their profit.
Apart from ISeq<BitGene>[], which takes some time getting used to (could I also use List or something similar?), I don't know how to create a proper codec:
@Override
public Codec<ISeq<BitGene>[], BitGene> codec() {
return Codecs.ofVector(
() -> {
// What kind of supplier do I need?
},
NUMBER_OF_KNAPSACKS);
}
If I understand your problem correctly, the codec would look like this:
Instead of an
ISeq<T>[]array, I'm using aISeq<ISeq<T>>, but the size of the first sequence will beknapsackCountand the size of the nested sequence isitmes.length(). The signature of your problem will beProblem<ISeq<ISeq<T>>, BitGene, Vec<double[]>>.