如何在 CPLEX OPL 中编写平均约束?

How to write average constraints in CPLEX OPL?

我有几个关于建模约束的问题。我想这应该很简单,但我无法弄清楚。首先,让我描述一下情况:我想优化一个多维背包问题。但是,我遇到了两个约束的一些困难。

我首先阅读的是 Excel sheet,其中包含以下列:

{string} Items = …;
tuple Item {
int weight;
int classification_1;
int classification_2;
…}

dvar int a[Items] in 0..1;

classification_1和classification_2是对象的两个独立分类,你可以想象,例如classification_1包含一个代表颜色的整数,而classification_2有另一个 属性 (例如形状,其中数字代表特定形状)。 为了更清楚地说明事情,你可以想象一个对象如下:

Ball_object; 23; 1; 2; …

其中 Ball_object 是名称,23 是重量,1 是蓝色,2 是圆形,其他属性与我的问题不直接相关。 现在假设我有以下约束: 1. 所有物品的重量不得超过所选物品总重量的10%。

我试过以下方法:

Subjected to {
    Forall ( i_1 in Items )
    ctItemRatio:
    (Item[i_1].weight * a[i_1]) / (sum (I in Items) (Item[i].weight * a[i])) <= 0.1;
}

但这似乎不起作用,因为我的 CPLEX studio 无法提取表达式。但是我对这个约束实际上做错了什么感到有点困惑。有谁知道我该如何解决这个问题?

  1. 对于每个形状,给定形状的总重量不应超过总重量的 15%。

我实际上并不知道如何做到这一点,因为我不能只遍历 classification_2 对吗?我如何建模才能通过 classification_2 使用 forall? (我很想找到一个 OPL 解决方案,而不是仅仅手动命名所有形状。

感谢您的帮助!

对于约束 #1,您编写它的方式是非线性的。如果你只是将两边乘以 sum (I in Items) (Item[i].weight * a[i]),它变成线性的,CPLEX 应该很高兴:

Item[i_1].weight * a[i_1] <= 0.1 * (sum (I in Items) (Item[i].weight * a[i]));

对于约束 #2,我建议构建一个 classification_2 的唯一值列表(在您调用 OPL 代码之前),然后遍历这些值,为每个值构建一个约束。我不熟悉 OPL 的语法,但大概您可以在总和中添加一个条件;类似于:

sum (i in Items : classification_2[i] == <some value>)