本文介绍了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条线的左半部分来看,将a [i]和a [j]放在一起将有助于c [i,j]达到目标值.这是当前正在实施,测试和运行的东西.

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

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

当我尝试使用IQuadNumExpr修改代码时,我发现它没有该.Constant属性.

是否可以在CPLEX中的二次目标函数中添加常数项?

解决方案

要回答您的特定问题,要向二次目标函数添加常量,可以使用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]

I'm using CPLEX 12.5.0.0 via the C# API.

Until now, I've never had a situation with an objective with a constant term - only constraints. With constraints, I have always been able to re-arrange the equation so the constant is always on one side, meaning each ILinearNumExpr has no constant term on its own.

Now I have a quadratic programming problem, with an objective of the following type:

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[,] is a constant, symmetric cost matrix. a[i] are binary variables.

So looking at the left halves of the 3 lines above, having both a[i] and a[j] together will contribute c[i,j] to the objective value. This is what is currently implemented, tested, and working.

I want to modify the objective so that, if a[i] and a[j] are not both equal to 1, rather than not contributing c[i,j] to the objective value, it will subtract it.

Now, I've looked up the CPLEX documentation (the authors of which are apparently allergic to providing clear explanations or examples), and there appears to be an ILinearNumExpr.Constant property that allows me to set a constant for a given expression.

When I tried to modify my code with IQuadNumExpr, I noticed it doesn't have that .Constant property.

Is there any way to add constant terms to a quadratic objective function in CPLEX?

解决方案

To answer your specific question, to add a constant to a quadratic objective function, you can use the .Sum method of the cplex object. For example

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

makes the objective function quadExpr + 10.

Now, two comments on the rest of your post.

First, any linear transformation on the objective function will have no effect on your solution. So, if you are maximizing either

quadExpr

or

m * quadExpr + c

are equivalent for any (nonzero) constant m and constant c.

Next, Since the variables in your quadratic expression are binary, then you can almost always do better by formulating a mixed-integer linear model. To do this, you create an additional set of linear variables, say b[i][j] that will be 1 only if both x[i] and a[j] are both 1. You can enforce the property of b[][] by adding the constraints

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

If you are maximizing, and c[i][j] >= 0, then you don't need to explicitly enforce the converse, but if that's not the case, you can add

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

这篇关于CPLEX二次程序的目标中的常数项吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-11 22:10