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

时间:2019-05-25 00:10:41

标签: cplex opl

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

我首先阅读包含以下列的Excel工作表:

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

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

分类_1和分类_2是对象的两个单独的分类,您可以想象,例如,分类_1包含代表颜色的整数,而分类_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%。

我实际上并不怎么知道该怎么做,因为我不能只遍历分类_2对吗?我如何对其建模,以便可以通过分类_2使用全部? (我很想找到一种OPL解决方案,而不仅仅是手工命名所有形状。

谢谢您的帮助!

1 个答案:

答案 0 :(得分:3)

对于约束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,我建议(在调用OPL代码之前)建立一个classification_2唯一值的列表,然后遍历这些值,为每个值建立约束。我不熟悉OPL的语法,但大概可以在总和中添加一个条件。像这样:

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