CPLEX二次规划的目标常数?

时间:2013-08-20 23:17:15

标签: mathematical-optimization cplex

我通过C#API使用CPLEX 12.5.0.0。

直到现在,我从未遇到过具有恒定术语的目标的情况 - 仅限制。有了约束,我总是能够重新排列等式,因此常量总是在一边,这意味着每个ILinearNumExpr本身没有常数项。

现在我遇到了二次规划问题,其目标是以下类型:

MAX Z = 
  c[1,2] * a[1] * a[2] - c[1,2] * (1 - a[1] * a[2]) +
  c[1,3] * a[1] * a[3] - c[1,2] * (1 - a[1] * a[3]) +
  c[2,3] * a[2] * a[3] - c[2,2] * (1 - a[2] * a[3])

c [,]是一个恒定的对称成本矩阵。 a [i]是二元变量。

因此,观察上面3行的左半部分,同时具有[i]和[j]将对目标值贡献c [i,j]。这是目前正在实施,测试和工作的内容。

我想修改目标,以便,如果[i]和[j]都不等于1,而不是将c [i,j]贡献给目标值,它将减去它。 / p>

现在,我查阅了CPLEX文档(其作者显然对提供明确的解释或示例过敏),并且似乎有一个ILinearNumExpr.Constant属性允许我为一个设置常量给出表达。

当我尝试使用IQuadNumExpr修改我的代码时,我注意到它没有.Constant属性。

有没有办法在CPLEX中为二次目标函数添加常量项?

1 个答案:

答案 0 :(得分:2)

要回答您的具体问题,要向二次目标函数添加常量,可以使用cplex对象的.Sum方法。例如

cplex.AddMaximize(cplex.sum(quadExpr, cplex.Constant(10));

制作目标函数quadExpr + 10

现在,对你帖子的其余部分发表两条评论。

首先,目标函数的任何线性变换都不会对您的解决方案产生影响。所以,如果你最大化

quadExpr

m * quadExpr + c

等于任何(非零)常数m和常数c。

接下来,由于二次表达式中的变量是二进制的,因此通过制定混合整数线性模型几乎总能做得更好。要做到这一点,你创建一组额外的线性变量,比如说b [i] [j]只有当x [i]和a [j]都是1时才会为1.你可以强制执行b []的属性[]通过添加约束

b[i][j] <= x[i]
b[i][j] <= x[j]

如果你正在最大化,并且c [i] [j]&gt; = 0,那么你不需要明确强制执行converse,但如果不是这样,你可以添加

x[i] + x[j] <= 1 + b[i][j]