2013-08-20 185 views
1

我通过C#API使用CPLEX 12.5.0.0。使用CPLEX进行二次规划的目标常数?

到现在为止,我从来没有过一个具有常数项的目标 - 只有约束条件。有了约束,我总能重新排列方程,所以常数总是在一边,这意味着每个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]是二元变量。

因此,看着上面三行的左半部分,将[i]和a [j]放在一起会使客观价值成为c [i,j]。这是目前实施,测试和工作的内容。

我想修改目标,以便如果[i]和a [j]不都等于1,而不是不向目标值贡献c [i,j],则会将其减去。

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

当我试图修改我的代码IQuadNumExpr,我注意到它没有那.Constant属性。

有什么方法可以将常数项添加到二次客观函数函数在CPLEX中吗?

+0

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]。那真的是你想要做的吗? –

+0

@DavidNehme是的,你可以重新安排这样的表达。我以这种形式离开,因为它更容易理解和解释。然而,重新安排并没有改变我的问题,因为在目标函数中仍然存在一个-c [1,2]常数项。 – Ozzah

+0

您可以忽略目标函数中的常数项。常数项不会改变最佳解决方案。另外,由于[i]是二进制的,所以最好将它建模为线性MIP。 –

回答

1

要回答您的具体问题,要向二次目标函数添加常数,可以使用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[i][j] <= x[i] 
b[i][j] <= x[j] 

如果你能够最大限度地执行B [] []的财产,和c [i] [j]> = 0,那么你就需要明确执行逆,但如果情况并非如此,则可以添加

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

感谢您的回答。正如我之前所说的,使模型线性化所增加的变量和限制实际上使解决问题需要更长的时间。我可以在几个小时内解决QP问题,而BIP可以持续很多天。 – Ozzah