1

我通过 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 行的左半部分,将 a[i] 和 a[j] 放在一起将为目标值贡献 c[i,j]。这是目前正在实施、测试和工作的内容。

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

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

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

有没有办法将常数项添加到CPLEX中的二次目标函数?

4

1 回答 1

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] >= 0,那么您不需要明确强制执行相反的操作,但如果不是这种情况,您可以添加

x[i] + x[j] <= 1 + b[i][j]
于 2013-08-21T04:39:40.977 回答