简体   繁体   English

为什么Cplex提供的解决方案缺乏约束?

[英]Why does Cplex provide a solution with slack on constraints?

I developed a linear mathematical programming model in Visual Studio (C++) and solved the problem using Cplex (12.7.1). 我在Visual Studio(C ++)中开发了线性数学编程模型,并使用Cplex(12.7.1)解决了该问题。 However I noticed some strange behavior of Cplex. 但是我注意到Cplex的某些奇怪行为。 For some problem instances, Cplex provides a feasible (non-optimal solution), that could be easily improved by removing slack on certain constraints. 对于某些问题实例,Cplex提供了一种可行的(非最佳解决方案),可以通过消除某些约束下的松弛来轻松地对其进行改进。 A simplified example of the mathematical model is as follows: 数学模型的简化示例如下:

Minimize A 最小化

Subject to 受制于

cX – dY <= A cX – dY <= A

dY – cX <= A dY – cX <= A

X, Y binary, A continuous, c,d parameters X,Y二进制,A连续,c,d参数

Given the values of X and Y in the provided feasible (non-optimal) solution, there is slack on both constraints. 给定所提供的可行(非最佳)解决方案中的X和Y值,两个约束都存在松弛。 The continuous A variable could be easily reduced given the values of decision variables X and Y (ie, by removing the slack of at least on of the two constraints). 给定决策变量X和Y的值,可以轻松地减少连续A变量(即,通过消除至少两个约束中的一个约束)。 I understand that Cplex provides a solution that is feasible given the constraints of the problem. 我了解Cplex提供了一个解决方案,考虑到问题的限制,该方案是可行的。 However when branching and solving the simplex in a branch to create a feasible solution, why does this simplex' calculation result in these two non-binding constraints? 但是,当在一个分支中分支并求解单纯形以创建可行的解决方案时,为什么这种单纯形的计算会导致这两个非约束性约束? What can I do to ensure Cplex always provides at least a solution in which one of these two constraints is binding? 如何确保Cplex始终提供至少两个约束之一绑定的解决方案?

  • I tried to include the solution without slack in order to test if the expected solution is recognised as a feasible solution by Cplex (ie, in order to test if the mathematical model programmed in C++ is error-free); 我尝试不松懈地包含解决方案,以测试Cplex是否将预期解决方案识别为可行的解决方案(即,为了测试用C ++编程的数学模型是否没有错误);
  • I tried to increase the Cplex' tolerances (IloCplex::Param::MIP::Tolerances::MIPGap); 我试图增加Cplex的容差(IloCplex :: Param :: MIP :: Tolerances :: MIPGap);
  • I tried to switch of the dynamic search of Cplex (IloCplex::Param::MIP::Strategy::Search). 我试图切换Cplex的动态搜索(IloCplex :: Param :: MIP :: Strategy :: Search)。

None of these tries solved the problem. 这些尝试都不能解决问题。

int nozones = 2;
int notrucks = 100;
int notimeslots = 24;
IloEnv env; 
IloModel model(env);
IloExpr objective(env);
IloExpr constraint(env);

NumVar3Matrix X(env, notimeslots);
for (i = 0; i < notimeslots; i++)
{
    X[i] = NumVarMatrix(env, notrucks);
    for (l = 0; l < notrucks; l++)
    {
        X[i][l] = IloNumVarArray(env, nozones);
        for (k = 0; k < nozones; k++)
        {
            X[i][l][k] = IloNumVar(env, 0, 1, ILOINT);
        }
    }
}

NumVar3Matrix A(env, nozones);
for (k = 0; k < nozones; k++)
{
    A[k] = NumVarMatrix(env, notimeslots);
    for (int i0 = 0; i0 < notimeslots; i0++)
    {
        A[k][i0] = IloNumVarArray(env, notimeslots);
        for (int i1 = 0; i1 < notimeslots; i1++)
        {
            A[k][i0][i1] = IloNumVar(env, 0, 9999, ILOFLOAT); 
        }
    }
}

//objective function
for (int k0 = 0; k0 < nozones; k0++)
{
    for (int i0 = 0; i0 < notimeslots; i0++)
    {
        for (int i1 = 0; i1 < notimeslots; i1++)
        {
            if (i0 > i1)
            {
                double denominator = (PP.mean[k0] * (double)(notimeslots*notimeslots)); //parameter
                objective += A[k0][i0][i1] / denominator;
            }
        }
    }
}

model.add(IloMinimize(env, objective)); 

//Constraints
for (int k0 = 0; k0 < nozones; k0++)
{
    for (int i0 = 0; i0 < notimeslots; i0++)
    {
        for (int i1 = 0; i1 < notimeslots; i1++)
        {
            if (i0 > i1)
            {
                for (int l0 = 0; l0 < notrucks; l0++)
                {
                    constraint += c[k0][l0] * X[i0][l0][k0];
                    constraint -= d[k0][l0] * X[i1][l0][k0];    
                }

                constraint -= A[k0][i0][i1];
                model.add(constraint <= 0);
                constraint.clear();

                for (int l0 = 0; l0 < notrucks; l0++)
                {
                    constraint -= c[k0][l0] * X[i0][l0][k0];
                    constraint += d[k0][l0] * X[i1][l0][k0];                
                }
                constraint -= A[k0][i0][i1];
                model.add(constraint <= 0);
                constraint.clear();
            }
        }
    }
}

Please find the log below: 请在下面找到日志:

CPXPARAM_TimeLimit                               10
CPXPARAM_Threads                                 3
CPXPARAM_MIP_Tolerances_MIPGap                   9.9999999999999995e-08
CPXPARAM_MIP_Strategy_CallbackReducedLP          0
Tried aggregator 2 times.
MIP Presolve eliminated 412 rows and 384 columns.
MIP Presolve modified 537 coefficients.
Aggregator did 21 substitutions.
Reduced MIP has 595 rows, 475 columns, and 10901 nonzeros.
Reduced MIP has 203 binaries, 0 generals, 0 SOSs, and 0 indicators.
Presolve time = 0.09 sec. (8.97 ticks)
Found incumbent of value 1254245.248934 after 0.11 sec. (10.55 ticks)
Probing time = 0.00 sec. (0.39 ticks)
Tried aggregator 1 time.
Reduced MIP has 595 rows, 475 columns, and 10901 nonzeros.
Reduced MIP has 203 binaries, 272 generals, 0 SOSs, and 0 indicators.
Presolve time = 0.03 sec. (4.47 ticks)
Probing time = 0.00 sec. (0.55 ticks)
Clique table members: 51.
MIP emphasis: balance optimality and feasibility.
MIP search method: dynamic search.
Parallel mode: deterministic, using up to 3 threads.
Root relaxation solution time = 0.05 sec. (15.41 ticks)

    Nodes                                         Cuts/
   Node  Left     Objective  IInf  Best Integer    Best Bound    ItCnt     Gap

*     0+    0                      1254245.2489    13879.8564            98.89%
*     0+    0                      1225612.3997    13879.8564            98.87%
*     0+    0                      1217588.5782    13879.8564            98.86%
*     0+    0                      1209564.7566    13879.8564            98.85%
*     0+    0                      1201540.9350    13879.8564            98.84%
*     0+    0                      1193517.1135    13879.8564            98.84%
*     0+    0                      1185493.2919    13879.8564            98.83%
*     0+    0                      1177589.9029    13879.8564            98.82%
      0     0   334862.8273   139  1177589.9029   334862.8273      387   71.56%
*     0+    0                       920044.8009   334862.8273            63.60%
      0     0   335605.5047   162   920044.8009     Cuts: 248      516   63.52%
*     0+    0                       732802.2256   335605.5047            54.20%
*     0+    0                       669710.6005   335605.5047            49.89%
      0     0   336504.5144   153   669710.6005     Cuts: 248      617   49.75%
      0     0   338357.1160   172   669710.6005     Cuts: 248      705   49.48%
      0     0   338950.0580   178   669710.6005     Cuts: 248      796   49.39%
      0     0   339315.6848   189   669710.6005     Cuts: 248      900   49.33%
      0     0   339447.9616   193   669710.6005     Cuts: 248      977   49.31%
      0     0   339663.6342   203   669710.6005     Cuts: 228     1091   49.28%
      0     0   339870.9021   205   669710.6005     Cuts: 210     1154   49.25%
*     0+    0                       531348.6042   339870.9021            36.04%
      0     0   340009.1008   207   531348.6042     Cuts: 241     1225   35.87%
      0     0   340855.1873   202   531348.6042     Cuts: 231     1318   35.85%
      0     0   341229.8328   202   531348.6042     Cuts: 248     1424   35.78%
      0     0   341409.5769   200   531348.6042     Cuts: 248     1502   35.75%
      0     0   341615.2848   286   531348.6042     Cuts: 248     1568   35.71%
      0     0   341704.8400   300   531348.6042     Cuts: 225     1626   35.69%
      0     0   341805.5681   222   531348.6042     Cuts: 191     1687   35.67%
*     0+    0                       489513.3319   341805.5681            30.17%
      0     0   341834.6048   218   489513.3319     Cuts: 169     1739   30.17%
      0     0   341900.1390   228   489513.3319     Cuts: 205     1788   30.16%
      0     0   341945.8278   211   489513.3319     Cuts: 197     1855   30.15%
*     0+    0                       489468.1697   341945.8278            30.14%
      0     2   341945.8278   202   489468.1697   341945.8278     1855   30.14%
Elapsed time = 5.53 sec. (446.68 ticks, tree = 0.01 MB, solutions = 14)
*   199+  154                       484741.1904   341968.3817            29.45%
    263   222   342462.1403   198   484741.1904   341968.3817    12287   29.45%
*   550+  420                       461678.3486   341993.1725            25.92%
    555   403   411858.3790   117   461678.3486   341993.1725    21480   25.92%
*   566+  319                       439985.4277   341993.1725            22.27%
    660   321   350009.7742   289   439985.4277   341993.1725    16141   22.27%
*   670+  427                       438464.9662   342020.7550            22.00%

Flow cuts applied:  15
Mixed integer rounding cuts applied:  65
Zero-half cuts applied:  6
Gomory fractional cuts applied:  15

Root node processing (before b&c):
  Real time             =    5.53 sec. (446.21 ticks)
Parallel b&c, 3 threads:
  Real time             =    4.50 sec. (1093.39 ticks)
  Sync time (average)   =    0.59 sec.
  Wait time (average)   =    0.04 sec.
                         ------------
Total (root+branch&cut) =   10.03 sec. (1539.61 ticks)

The expected result is that in all feasible solutions that Cplex provides, for all pairs of constraints that at least on of them is binding (without slack). 预期的结果是,在Cplex提供的所有可行解决方案中,对于所有约束对,至少其中一对约束是绑定的(没有懈怠)。

I assume CPLEX aborted due to hitting your time limit, hence the solution was not proven to be an optimum. 我认为CPLEX由于达到您的时间限制而中止,因此该解决方案未被证明是最佳的。 Is this correct ? 这个对吗 ?

This is not a bug. 这不是错误。 CPLEX does not make such guarantees for a user terminated run. 对于用户终止的运行,CPLEX不提供此类保证。 CPLEX stops as soon as possible, when a solution satisfying the user requests/settings is found. 当找到满足用户请求/设置的解决方案时,CPLEX会尽快停止。

To get the behavior your are looking for, then in the C API you can use : 要获得您想要的行为,则可以在C API中使用:

https://www.ibm.com/support/knowledgecenter/en/SSSA5P_12.9.0/ilog.odms.cplex.help/CPLEX/UsrMan/topics/discr_optim/mip/para/51_soln_fixed.html https://www.ibm.com/support/knowledgecenter/zh-CN/SSSA5P_12.9.0/ilog.odms.cplex.help/CPLEX/UsrMan/topics/discr_optim/mip/para/51_soln_fixed.html

to solve the fixed problem. 解决固定的问题。 Since the resulting problem is a pure LP, you can now call : 由于产生的问题是纯LP,因此您现在可以致电:

  • CPXlpopt() which solves this fixed LP 解决此固定LP的CPXlpopt()
  • query duals etc. from the LP solve. 从LP查询对偶等。

And as mentioned in the link you can use solveFixed() for higher level API's. 并且如链接中所述,您可以将solveFixed()用于更高级别的API。

Daniel also answered your cross-post here : 丹尼尔(Daniel)也在这里回答了您的交叉帖子:

https://developer.ibm.com/answers/questions/499882/why-does-cplex-provide-feasible-solutions-with-con/ https://developer.ibm.com/answers/questions/499882/why-does-cplex-provide-feasible-solutions-with-con/

https://developer.ibm.com/answers/questions/499879/why-does-cplex-provide-slack-on-constraints-when-p/ https://developer.ibm.com/answers/questions/499879/why-does-cplex-provide-slack-on-constraints-when-p/

Please reply at the IBM developer forum if anything is not clear, thank you. 如果不清楚,请在IBM开发人员论坛上回复,谢谢。

I think I know the answer to that. 我想我知道答案。

Cplex's heuristics will sometimes find integer solutions that are LP non-optimal. Cplex的启发式方法有时会找到LP非最佳的整数解。 Here is an example of this behavior. 这是此行为的示例 This can really generate incoherent solutions. 这确实会产生不连贯的解决方案。 Many MIP modeling constructs (absolute values, min/max formulations, etc) assume all integer solutions are LP optimal. 许多MIP建模构造(绝对值,最小/最大公式等)都假定所有整数解都是LP最优的。 Preferably, Cplex would clean up these solutions. Cplex最好清理这些解决方案。

A workaround I use for this problem is the following. 下面是我用于此问题的解决方法。 After Cplex stops with a MIP solution, always fix all discrete variables and resolve as an LP. Cplex停止使用MIP解决方案后,请务必修复所有离散变量并将其解析为LP。 This will clean up integer solutions that are LP non-optimal. 这将清除LP非最佳的整数解决方案。 One possible exception: if the problem is proven globally optimal, then this may not be needed (I have become somewhat paranoid about this, so I always add the final LP). 一个可能的例外:如果问题被证明是全局最优的,那么可能就不需要(我对此有些偏执,所以我总是添加最终的LP)。 I have not seen this behavior (yet) with other solvers. 我尚未与其他求解器一起看到此行为。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM