【问题标题】:Constant term in objective for quadratic program with CPLEX?使用 CPLEX 的二次程序的目标中的常数项?
【发布时间】:2013-08-20 23:17:15
【问题描述】:

我通过 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 中向 二次目标 函数添加常数项?

【问题讨论】:

  • c[1,2]a[1]a[2] - c[1,2] (1-a[1]a[2]) == 2c[1,2]x [1]x[2] - c[1,2]。这真的是你想要做的吗?
  • @DavidNehme 是的,您可以像这样重新排列表达式。我离开这个表格是因为它更容易理解和解释。然而,重新安排并没有改变我的问题,因为目标函数中仍然存在 -c[1,2] 常数项。
  • 您可以忽略目标函数中的常数项。常数项不会改变最优解。此外,由于 a[i] 是二进制的,因此最好将其建模为线性 MIP。
  • 我可能遗漏了一些东西——如果你的目标是最小化 f(x) + c,你不能只是最小化 f(x) 然后再添加 c 吗?否则,我的作弊者的回答是,您可以将二进制变量的乘积重写为二进制变量本身,并摆脱整个二次 MIP 情况(需要注意的是您必须在问题中添加更多变量)。
  • @DavidNehme 如果我将其表述为 MIP(就像我最初所做的那样),那么变量的数量会激增,并且模型会运行一周而没有找到最佳解决方案。如果我将其设为 QAP,那么它会在 12 小时内找到最佳状态。

标签: mathematical-optimization cplex


【解决方案1】:

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

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

使目标函数quadExpr + 10

现在,您的帖子的其余部分有两个 cmets。

首先,目标函数的任何线性变换都不会影响您的解决方案。因此,如果您要最大化其中一个

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]

【讨论】:

  • 感谢您的回答。正如我之前所说,使模型线性化所涉及的附加变量和约束实际上使求解时间显着延长。我可以在几个小时内解决 QP,而 BIP 会持续很多很多天。
猜你喜欢
  • 2016-12-21
  • 1970-01-01
  • 2021-09-22
  • 2019-02-09
  • 1970-01-01
  • 2019-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多