我正在尝试编写一个可以解决多项选择背包问题 (MCKP) 的模型,如涉及维度、需求和多项选择约束的背包问题中所述:公式之间的泛化和转换(在此处找到,参见图 8 和图 9)。您可以在此处找到基本背包问题的示例 GPL 模型。对于寻求快速解释背包问题的任何人,请阅读以下插图:
你是一个冒险家,偶然发现了一个宝库。有数百个美妙的项目“i”,每个都有一个重量“w”和一个利润“p”。假设您有一个重量为“c”的背包,并且您想在不使背包装满的情况下获得最大的利润。使您获得最大利润的项目的最佳组合是什么?
在代码中:
maximize obj :
sum{(i,w,p) in I} p*x[i];
其中“I”是一篮子物品,x[i] 是二元变量(0 = 未选择,1 = 已选择)
我遇到的问题是添加了多个组。MCKP 要求从每个组中只选择一项。因此,例如,假设我们有三个可供选择的组。它们可以表示如下(忽略实际值):
# Items: index, weight, profit
set ONE :=
1 10 10
2 10 10
3 15 15
4 20 20
5 20 20
6 24 24
7 24 24
8 50 50;
# Items: index, weight, profit
set TWO :=
1 10 10
2 10 10
3 15 15
4 20 20
5 20 20
6 24 24
7 24 24
8 50 50;
# Items: index, weight, profit
set THREE :=
1 10 10
2 10 10
3 15 15
4 20 20
5 20 20
6 24 24
7 24 24
8 50 50;
我对如何迭代每个组以及如何定义变量 x 感到困惑。我认为它看起来像:
var x{i,j} binary;
其中 i 是组 j 中项目的索引。这假设我定义了一组集合:
set Groups{ONE,TWO,THREE}
然后我会遍历项目组:
sum{j in Groups, (i,w,p) in Groups[j]} p*x[i,j];
但我很担心,因为我相信 GPL 不支持有序集。我已经看到了这个相关的问题,其中答案建议在集合中定义一个集合。但是,我不确定它在这种特定情况下如何应用。
我的主要问题要明确:在 GPL 中,我如何迭代集合(在这种情况下是一组组,其中每个组都有一组项目)?