Decision Optimization

Decision Optimization

Delivers prescriptive analytics capabilities and decision intelligence to improve decision-making.

 View Only
  • 1.  User cut pool not applied

    Posted Fri April 08, 2016 09:33 AM

    Originally posted by: manerg


    Hello,
    I'd like to use a set of constraints as User Cuts in the specific pool. However, cuts seem to be ignored and the following line appears at the end of the computation:
    Warning:  User cuts freed during column deletion.

    Here is the log:

    Tried aggregator 2 times.
    MIP Presolve eliminated 1304 rows and 1242 columns.
    Aggregator did 705 substitutions.
    Reduced MIP has 2603 rows, 2279 columns, and 13776 nonzeros.
    Reduced MIP has 728 binaries, 0 generals, 0 SOSs, and 0 indicators.
    Presolve time = 0.02 sec. (11.29 ticks)
    Found incumbent of value 23175.950000 after 0.05 sec. (17.42 ticks)
    Probing fixed 0 vars, tightened 260 bounds.
    Probing time = 0.05 sec. (11.75 ticks)
    Tried aggregator 1 time.
    MIP Presolve modified 260 coefficients.
    Reduced MIP has 2603 rows, 2279 columns, and 13776 nonzeros.
    Reduced MIP has 728 binaries, 0 generals, 0 SOSs, and 0 indicators.
    Presolve time = 0.02 sec. (6.10 ticks)
    Probing time = 0.03 sec. (5.03 ticks)
    Clique table members: 9211.
    Problem contains 200 user cuts.
    MIP emphasis: balance optimality and feasibility.
    MIP search method: dynamic search.
    Parallel mode: deterministic, using up to 8 threads.
    Root relaxation solution time = 0.03 sec. (21.52 ticks)
            Nodes                                         Cuts/
       Node  Left     Objective  IInf  Best Integer    Best Bound    ItCnt     Gap
    *     0+    0                        23175.9500  -170865.2400           837.25%
          0     0    10616.5221    15    23175.9500    10616.5221     1123   54.19%
    *     0+    0                        18600.3000    10616.5221            42.92%
          0     0    11105.5682    79    18600.3000     Cuts: 199     1490   40.29%
    *     0+    0                        14844.0600    11105.5682            25.19%
    *     0+    0                        13196.4360    11105.5682            15.84%
          0     0    11172.1561   167    13196.4360     Cuts: 152     2122   15.34%
          0     0    11203.5274   183    13196.4360     Cuts: 207     2571   14.36%
    *     0+    0                        12859.4600    11300.9540            12.12%
    *     0+    0                        12465.6440    11300.9540             9.34%
          0     0    11223.5372   111    12465.6440     Cuts: 103     2874    2.01%
          0     0    11226.4308   242    12465.6440      Cuts: 98     3164    0.01%
          0     0    11227.4764   106    12465.6440      Cuts: 21     3238    0.01%
          0     0    11228.0839   117    12465.6440      Cuts: 56     3302    0.01%
          0     2    11228.0839   112    12465.6440    12464.4020     3302    0.01%
    Elapsed time = 2.61 sec. (1491.72 ticks, tree = 0.00 MB, solutions = 6)
          8     6    12285.8978    63    12465.6440    12464.4020     6952    0.01%
         37     3    12344.8959    36    12465.6440    12464.4020    12324    0.01%
    GUB cover cuts applied:  2
    Cover cuts applied:  2
    Implied bound cuts applied:  30
    Flow cuts applied:  14
    Mixed integer rounding cuts applied:  70
    Lift and project cuts applied:  1
    Gomory fractional cuts applied:  2
    Root node processing (before b&c):
      Real time             =    2.57 sec. (1475.67 ticks)
    Parallel b&c, 8 threads:
      Real time             =    0.98 sec. (553.50 ticks)
      Sync time (average)   =    0.58 sec.
      Wait time (average)   =    0.63 sec.
                              ------------
    Total (root+branch&cut) =    3.56 sec. (2029.17 ticks)
    Warning:  User cuts freed during column deletion.
    

    Why does this happens? 
    Thanks in advance,

    Daniele

     


    #CPLEXOptimizers
    #DecisionOptimization


  • 2.  Re: User cut pool not applied

    Posted Tue April 19, 2016 04:08 AM

    Sorry for the long delay.

    What API do you use and how exactly do you specify the cuts? Do you add them to a pool before starting the solve or do you inject them via a callback?

    This "User cuts freed ..." message looks odd. Do you have a small code sample to reproduce this issue? Do things work any better if you disable non-linear reductions by setting CPX_PARAM_LINEAR to 0?


    #CPLEXOptimizers
    #DecisionOptimization


  • 3.  Re: User cut pool not applied

    Posted Tue April 19, 2016 09:14 AM

    Originally posted by: manerg


    Thanks for your reply, Daniel!
    In these days I have worked out some issues.

    For example, I understood that the warning comes out only AFTER the solving process, when I end the cplex variables and data structures! And this makes sense.
    Hence, in my previous example, the user cuts were not applied because of a solver choice.
    I have also found some examples in which user cuts are really applied (this is written at the end of the process).

    However, if I generate the same cuts during the process via callback, a lot of these cuts are separated and added (let's say hundreds). If I used the pool, instead, very few (let's say, less than 10) or none of the cuts are used to strengthen the model. And the convergence is slower.

    Shouldn't be the cuts added for (almost) the same number?

    Thanks again,
    Daniele

     


    #CPLEXOptimizers
    #DecisionOptimization


  • 4.  Re: User cut pool not applied

    Posted Sun April 24, 2016 09:16 AM

    Originally posted by: AndreaTramontani


    Dear Daniele,

    there are three fundamental differences between user cuts separated with a usercut callback and usercuts stored in the usercut pool.
    I think all of those differences can play a role in your case, and create this difference you observe in the number of usercuts applied.

     

    1. The first difference is about strategies for filtering the cuts.

    When you add usercuts with a callback, you call CPXXcutcallbackadd (assuming you are using C APIs).
    As specified in the documentation (www.ibm.com/support/knowledgecenter/SSSA5P_12.6.3/ilog.odms.cplex.help/refcallablelibrary/mipapi/cutcallbackadd.html)
    this callback has a parameter, 'int purgeable', that you can use to specify which strategy CPLEX should apply to manage your cut.
    The possible values for purgeable are:
    CPX_USECUT_FORCE:  
       The cut is added to the relaxation and stays there
    CPX_USECUT_PURGE:  
       The cut is added to the relaxation but can be purged later on if CPLEX deems the cut ineffective.
    CPX_USECUT_FILTER:
       The cut is treated exactly as cuts generated by CPLEX; that is, CPLEX applies its filtering process and may not even add the cut to the relaxation, for example, if CPLEX deems other cuts more effective, or if the cut is too dense.

    If you are using other APIs then nothing changes since you still have the same possibility.

    On the contrary, you don't have any control on the strategies for filtering the cuts, with cuts stored in the usercut pool.
    I can tell you that for usercut in the pool the strategy is equivalent to CPX_USECUT_PURGE above, but there is no way to change it.

    This difference can play an important role if most of the user cuts are separated at the root node.
    I don't know which strategy you are using when adding cuts from usercut callback, but if you use CPX_USECUT_FORCE then this might explain the differences.
    Please note that the number of usercuts applied reported at the end in the log reflects the number of usercuts present in the final relaxation.
    Thus, cuts that are added to the relaxation but then purged (i.e., removed) afterwards will not be counted in those final statistics.

     

    2. The second difference is about strategies to give up with cut separation.

    When your usercut callback is called, it receives on input the 'wherefrom' parameter, that in the case of a usercut callback can have 2 values:
    CPX_CALLBACK_MIP_CUT_LOOP: callback called inside the CPLEX cut loop, when CPLEX is also generating its own cuts
    CPX_CALLBACK_MIP_CUT_LAST: callback called after the CPLEX cut loop, when CPLEX has decided to stop generating its own cuts

    So, usercuts stored in the pool are only separated together with CPLEX cuts, during CPLEX cut loop.
    If you instead use a callback, then you can be more aggressive and separate usercuts also when CPLEX has decided to stop separating cuts.

     

    3. The third difference is about separation strategies during the branch-and-bound, i.e., cut separation in the tree.

    If you have a usercut callback installed, this is called at every node (every node with an optimal solution that is fractional, of course),
    and thus you have a lot of flexibility in deciding when/if separating the cuts.

    On the other hand, usercuts stored in the pool are separated only together with other CPLEX cuts.
    In the tree, CPLEX is quite conservative with cut separation. It does not separate cuts at every node, but only at some nodes, depending on some internal rules/strategies.
    Therefore there might be many nodes at which usercuts in the pool are not separated, but CPLEX stll calls the usercut callback.


    #CPLEXOptimizers
    #DecisionOptimization