Cplex Refiner:如何仅添加左手或右手的现有约束?
Cplex Refiner: How to add existing Constraints only left- or right-handed?
cplex 精简器发现了破坏的约束。我想向用户展示有关其模型实际冲突的详细信息。
因此我想将矩阵的每个约束拆分为单独的约束。左撇子和右撇子。示例:
10 <= x1 <= 40
应该变成
10 <= x1 <= infinity
-infinity <= x1 <= 40
这在数学上是相等的。
IBM 关于 cplex 精炼器 (http://www-01.ibm.com/support/docview.wss?uid=swg21429472) 的示例使用这段代码来考虑约束:
for (int c1 = 0; c1 < rng.Length; c1++)
{
constraints[c1] = rng[c1];
}
我稍微更新了它,以拆分约束(请注意:IBM 的示例大量使用约束数组的索引。所有这些位置也需要更新)
for (int c1 = 0; c1 < rng.Length; c1++)
{
constraints[c1] = cplex.Ge(rng[c1].Expr, rng[c1].LB);
}
for (int c1 = 0; c1 < rng.Length; c1++)
{
constraints[rng.Length + c1] = cplex.Le(rng[c1].Expr, rng[c1].UB);
}
这是我使用的模型文件。 (x1 的边界显然与 c3 和 c4 冲突。)
Maximize
obj: x1 + 2 x2 + 3 x3
Subject To
c1: x2 + x3 <= 20
c2: x1 - 3 x2 + x3 <= 30
c3: x1 <= 40
c4: x1 >= 40
Bounds
10 <= x1 <= 10
Generals
x1 x2 x3
End
具有拆分约束的更新版本的代码打印出损坏的结果(先是左侧,然后是右侧)。它只显示 x1 是冲突的一部分(你不能认为它本身就是冲突。它需要有一个伙伴!)
Solution status = Infeasible
Model Infeasible, Calling CONFLICT REFINER
Number of SOSs=0
IloRange : -infinity <= (1*x2 + 1*x3) <= infinity
IloRange : -infinity <= (1*x1 - 3*x2 + 1*x3) <= infinity
IloRange : -infinity <= (1*x1) <= infinity
IloRange : 40 <= (1*x1) <= infinity
IloRange : -infinity <= (1*x2 + 1*x3) <= 20
IloRange : -infinity <= (1*x1 - 3*x2 + 1*x3) <= 30
IloRange : -infinity <= (1*x1) <= 40
IloRange : -infinity <= (1*x1) <= infinity
Lower bound of x1
Upper bound of x1
Lower bound of x2
Upper bound of x2
Lower bound of x3
Upper bound of x3
Conflict Refinement process finished: Printing Conflicts
Proved : Upper bound of x1
Conflict Summary:
Constraint conflicts = 0
Variable Bound conflicts = 1
SOS conflicts = 0
Calling FEASOPT
原版的双手约束打印出了预期的结果(c4和x1有部分冲突)
Solution status = Infeasible
Model Infeasible, Calling CONFLICT REFINER
Number of SOSs=0
IloRange c1 : -infinity <= (1*x2 + 1*x3) <= 20
IloRange c2 : -infinity <= (1*x1 - 3*x2 + 1*x3) <= 30
IloRange c3 : -infinity <= (1*x1) <= 40
IloRange c4 : 40 <= (1*x1) <= infinity
Lower bound of x1
Upper bound of x1
Lower bound of x2
Upper bound of x2
Lower bound of x3
Upper bound of x3
Conflict Refinement process finished: Printing Conflicts
Proved : IloRange c4 : 40 <= (1*x1) <= infinity
Proved : Upper bound of x1
Conflict Summary:
Constraint conflicts = 1
Variable Bound conflicts = 1
SOS conflicts = 0
Calling FEASOPT
RefineConflict 的文档对 cons
参数说明如下:
An array of constraints. They may be IRange or IAnd constructs on a
set of ranges. Only constraints directly added to the model can be
specified.
在您修改后的代码段中,您正在向 constraints
数组添加新约束,其中 未 被添加到模型中(例如,您使用 Ge
方法而不是 AddGe
方法)。
我想您可以执行以下操作:
cplex.Remove(rng); // First remove the original constraints
for (int c1 = 0; c1 < rng.Length; c1++)
{
IRange tmp = rng[c1];
// Now, add new constraints to the model and save them in the constraints array.
constraints[c1] = cplex.AddGe(tmp.Expr, tmp.LB);
constraints[rng.Length + c1] = cplex.AddLe(tmp.Expr, tmp.UB);
}
您应该在调用 RefineConflict
之前添加以下行,以确保修改后的模型看起来像您期望的那样:
cplex.ExportModel("modified.lp");
cplex 精简器发现了破坏的约束。我想向用户展示有关其模型实际冲突的详细信息。
因此我想将矩阵的每个约束拆分为单独的约束。左撇子和右撇子。示例:
10 <= x1 <= 40
应该变成
10 <= x1 <= infinity
-infinity <= x1 <= 40
这在数学上是相等的。
IBM 关于 cplex 精炼器 (http://www-01.ibm.com/support/docview.wss?uid=swg21429472) 的示例使用这段代码来考虑约束:
for (int c1 = 0; c1 < rng.Length; c1++)
{
constraints[c1] = rng[c1];
}
我稍微更新了它,以拆分约束(请注意:IBM 的示例大量使用约束数组的索引。所有这些位置也需要更新)
for (int c1 = 0; c1 < rng.Length; c1++)
{
constraints[c1] = cplex.Ge(rng[c1].Expr, rng[c1].LB);
}
for (int c1 = 0; c1 < rng.Length; c1++)
{
constraints[rng.Length + c1] = cplex.Le(rng[c1].Expr, rng[c1].UB);
}
这是我使用的模型文件。 (x1 的边界显然与 c3 和 c4 冲突。)
Maximize
obj: x1 + 2 x2 + 3 x3
Subject To
c1: x2 + x3 <= 20
c2: x1 - 3 x2 + x3 <= 30
c3: x1 <= 40
c4: x1 >= 40
Bounds
10 <= x1 <= 10
Generals
x1 x2 x3
End
具有拆分约束的更新版本的代码打印出损坏的结果(先是左侧,然后是右侧)。它只显示 x1 是冲突的一部分(你不能认为它本身就是冲突。它需要有一个伙伴!)
Solution status = Infeasible
Model Infeasible, Calling CONFLICT REFINER
Number of SOSs=0
IloRange : -infinity <= (1*x2 + 1*x3) <= infinity
IloRange : -infinity <= (1*x1 - 3*x2 + 1*x3) <= infinity
IloRange : -infinity <= (1*x1) <= infinity
IloRange : 40 <= (1*x1) <= infinity
IloRange : -infinity <= (1*x2 + 1*x3) <= 20
IloRange : -infinity <= (1*x1 - 3*x2 + 1*x3) <= 30
IloRange : -infinity <= (1*x1) <= 40
IloRange : -infinity <= (1*x1) <= infinity
Lower bound of x1
Upper bound of x1
Lower bound of x2
Upper bound of x2
Lower bound of x3
Upper bound of x3
Conflict Refinement process finished: Printing Conflicts
Proved : Upper bound of x1
Conflict Summary:
Constraint conflicts = 0
Variable Bound conflicts = 1
SOS conflicts = 0
Calling FEASOPT
原版的双手约束打印出了预期的结果(c4和x1有部分冲突)
Solution status = Infeasible
Model Infeasible, Calling CONFLICT REFINER
Number of SOSs=0
IloRange c1 : -infinity <= (1*x2 + 1*x3) <= 20
IloRange c2 : -infinity <= (1*x1 - 3*x2 + 1*x3) <= 30
IloRange c3 : -infinity <= (1*x1) <= 40
IloRange c4 : 40 <= (1*x1) <= infinity
Lower bound of x1
Upper bound of x1
Lower bound of x2
Upper bound of x2
Lower bound of x3
Upper bound of x3
Conflict Refinement process finished: Printing Conflicts
Proved : IloRange c4 : 40 <= (1*x1) <= infinity
Proved : Upper bound of x1
Conflict Summary:
Constraint conflicts = 1
Variable Bound conflicts = 1
SOS conflicts = 0
Calling FEASOPT
RefineConflict 的文档对 cons
参数说明如下:
An array of constraints. They may be IRange or IAnd constructs on a set of ranges. Only constraints directly added to the model can be specified.
在您修改后的代码段中,您正在向 constraints
数组添加新约束,其中 未 被添加到模型中(例如,您使用 Ge
方法而不是 AddGe
方法)。
我想您可以执行以下操作:
cplex.Remove(rng); // First remove the original constraints
for (int c1 = 0; c1 < rng.Length; c1++)
{
IRange tmp = rng[c1];
// Now, add new constraints to the model and save them in the constraints array.
constraints[c1] = cplex.AddGe(tmp.Expr, tmp.LB);
constraints[rng.Length + c1] = cplex.AddLe(tmp.Expr, tmp.UB);
}
您应该在调用 RefineConflict
之前添加以下行,以确保修改后的模型看起来像您期望的那样:
cplex.ExportModel("modified.lp");