Search code examples
julialinear-programmingcplexmixed-integer-programming

Why the limits of the number of solutions in cplex is not taken into consideration?


I'm solving a MILP problem with CPLEX called from Julia JuMP package. In CPLEX log the number of solutions is displayed to be more than 3000, but there is the parameter CPXPARAM_MIP_Limits_Solutions set to 55, so the solver should return when the number of solution is more than 55. The explosion of the number of solution causes an out of memory error, therefore the Linux kernel kills the process.

This is the log:

CPXPARAM_Emphasis_Memory                         1
CPXPARAM_Emphasis_MIP                            2
CPXPARAM_MIP_Limits_Solutions                    55
CPXPARAM_TimeLimit                               60
Warning:  Non-integral bounds for integer variables rounded.
2 of 3 MIP starts provided solutions.
MIP start 'm1' defined initial solution with objective 0.0000.
Warning:  Non-integral bounds for integer variables rounded.
Tried aggregator 2 times.
MIP Presolve eliminated 12094 rows and 182224 columns.
MIP Presolve added 26 rows and 0 columns.
MIP Presolve modified 17428 coefficients.
Aggregator did 1 substitutions.
Reduced MIP has 5863 rows, 4313 columns, and 28322 nonzeros.
Reduced MIP has 4132 binaries, 175 generals, 0 SOSs, and 0 indicators.
Presolve time = 0.35 sec. (311.81 ticks)
Probing fixed 3059 vars, tightened 200 bounds.
Probing changed sense of 57 constraints.
Probing time = 0.45 sec. (324.14 ticks)
Cover probing fixed 0 vars, tightened 286 bounds.
Tried aggregator 2 times.
MIP Presolve eliminated 4435 rows and 3257 columns.
MIP Presolve modified 923 coefficients.
Aggregator did 2 substitutions.
Reduced MIP has 1426 rows, 1054 columns, and 7403 nonzeros.
Reduced MIP has 929 binaries, 122 generals, 0 SOSs, and 0 indicators.
Presolve time = 0.02 sec. (19.58 ticks)
Probing time = 0.03 sec. (18.90 ticks)
Tried aggregator 1 time.
MIP Presolve eliminated 5 rows and 3 columns.
MIP Presolve modified 1 coefficients.
Reduced MIP has 1421 rows, 1051 columns, and 7378 nonzeros.
Reduced MIP has 927 binaries, 121 generals, 0 SOSs, and 0 indicators.
Presolve time = 0.01 sec. (7.48 ticks)
Probing time = 0.08 sec. (52.47 ticks)
Clique table members: 6451.
MIP emphasis: optimality.
MIP search method: dynamic search.
Parallel mode: deterministic, using up to 32 threads.
Root relaxation solution time = 0.02 sec. (14.70 ticks)

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

*     0+    0                            0.0000  -106269.5431              --- 
      0     0     -463.9717    61        0.0000     -463.9717      480     --- 
      0     0     -454.9015   109        0.0000      Cuts: 86      537     --- 
      0     0     -434.5372   112        0.0000      Cuts: 87      592     --- 
      0     0     -426.6747   113        0.0000      Cuts: 97      622     --- 
      0     0     -418.6204   136        0.0000      Cuts: 62      660     --- 
      0     0     -413.7867   132        0.0000      Cuts: 55      698     --- 
      0     0     -409.6387   140        0.0000      Cuts: 16      721     --- 
      0     0     -407.9923   135        0.0000      Cuts: 39      739     --- 
      0     0     -407.0012   148        0.0000      Cuts: 34      760     --- 
      0     0     -406.3034   149        0.0000      Cuts: 11      775     --- 
      0     0     -405.7757   134        0.0000      Cuts: 17      784     --- 
      0     0     -405.4831   148        0.0000      Cuts: 59      804     --- 
      0     2     -405.4831   145        0.0000     -118.6877      804     --- 
Elapsed time = 2.12 sec. (1148.70 ticks, tree = 0.02 MB, solutions = 2)
*   282    17      integral     0        0.0000     -118.6877     3889     --- 
   6415  1365       -0.0974     1        0.0000       -0.1947    20809     --- 
  11118  1933     -348.8038   138        0.0000       -0.1947    37285     --- 
* 11185    11      integral     0        0.0000       -0.1947    37522     --- 
* 11206    16      integral     0       -0.0000       -0.1947    37594     --- 
  12049   384       -0.0974     1       -0.0000       -0.1947    39994     --- 
  13976  1504       -0.0974     1       -0.0000       -0.1947    44560     --- 
  15081  1894       -0.0974     1       -0.0000       -0.1947    47408     --- 
  16098  2205       -0.0000     0       -0.0000       -0.1947    49781     --- 
  17468  2844       -0.0974     1       -0.0000       -0.1947    52969     --- 
  18578  3322       -0.0000     0       -0.0000       -0.1947    56013     --- 
  19990  1939       -0.0000     0       -0.0000       -0.1947    61970     --- 
Elapsed time = 14.88 sec. (4728.96 ticks, tree = 2.14 MB, solutions = 3127)
  21354   555        cutoff             -0.0000       -0.1947    67537     --- 
  26500   824       -0.0974     1       -0.0000       -0.1431    79682     --- 
Killed

Version:

CPLEX 12.9.0 Julia 1.2.0 JuMP 0.20.1

Edit:

CPXPARAM_MIP_Limits_Solutions parameter controls the maximum number of incumbent solution to be found before stopping the optimization. However this number is not enough to control the number of solutions that the solver keeps in memory, because there may be the case when there are multiple solutions that are equivalent in terms of their value of the objective function, and in this case they just count for one solution for CPXPARAM_MIP_Limits_Solutions purpose. Therefore, to avoid memory consumption caused by solutions stored by the solver the right parameter is CPXPARAM_MIP_Pool_Capacity (that controls the number of solutions explored by the solver) that I set to 0 (because I was not interested in getting back all the solutions explored by CPLEX, but just the best one). After this configuration the program terminated its run without being killed by the kernel.


Solution

  • The number of solutions is very likely not the reason for the out-of-memory error. It's the size of the branch-and-bound tree and the number of nodes that need to be stored and processed. You should try limiting the number of threads that are used to reduce the memory footprint.

    Furthermore, there aren't that many proper solutions found. For every new incumbent you see a marker (* or H) at the beginning of the respective line, e.g.,

    *   282    17      integral     0        0.0000     -118.6877     3889     --- 
       6415  1365       -0.0974     1        0.0000       -0.1947    20809     --- 
      11118  1933     -348.8038   138        0.0000       -0.1947    37285     --- 
    * 11185    11      integral     0        0.0000       -0.1947    37522     --- 
    * 11206    16      integral     0       -0.0000       -0.1947    37594     --- 
      12049   384       -0.0974     1       -0.0000       -0.1947    39994     --- 
    

    I don't know what the number of solutions reported in the log refers to. Probably these are additional solutions that do not improve the objective.

    Please note the description of the parameter CPXPARAM_MIP_Limits_Solutions in the CPLEX docu:

    Sets the number of MIP solutions to be found before stopping.

    This integer solution limit does not apply to the populate procedure, which generates solutions to store in the solution pool. For a limit on the number of solutions generated by populate, see the populate limit parameter: maximum number of solutions generated for solution pool by populate.

    You may want to check the CPXPARAM_MIP_Limits_Populate parameter as well.