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 beknapsackCount
and the size of the nested sequence isitmes.length()
. The signature of your problem will beProblem<ISeq<ISeq<T>>, BitGene, Vec<double[]>>
.