Decision Optimization

Decision Optimization

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


#Analytics
#DecisionOptimization
#DecisionOptimization
 View Only
  • 1.  Benders Decomposition in Python

    Posted 12/14/16 03:34 PM

    Originally posted by: ccasorra


    Hi all,

    I've tried implementing Benders on a MIP using the annotations and bender.strategy parameter that has been introduced recently in CPLEX 12.7.

    My MIP has three sets of variables: Continuous c[j] for all j in J, binary q[k,j] for all k in K and j in J and continuous y[k,l,j] for all k in K, l in J and j in J.

    So, I build up my model:

    m1 = ERASERMIPpS.solveMIPpS(K, J, p, m, UDC, UDU, UAC, UAU)

    And I annotate my variables as follows, leaving the c and the q variables in the master (I don't annotate these as their default value is 0), and sending the y[k,l,j] variables to K separations problems:

    cpxBendersPartition=m1.long_annotations.add(name='cpxBendersPartition', defval=0)

    variables=m1.long_annotations.object_type.variable

    for k in range(K):

           for i in range(J*K+J+(J*J)*k,J*K+J+J*J+(J*J)*k,1):
                     m1.long_annotations.set_values(cpxBendersPartition,variables,i,k+1)

    Just to make sure that I'm annotating correctly, I print out the annotation:

    print m1.long_annotations.get_values(cpxBendersPartition,variables)

    For a small example where J=2, K=3, the first 2 variables are the c variables, the next 6 are the q's and the rest are the y variables. And, indeed, printing out the annotation I get:

    [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3]

    which corresponds to the c and q variables being left in the master and the y variables being sent to K=3 different subproblems. Then, I set the benders.strategy parameter to 0 and solve:

    m1.parameters.benders.strategy.set(0)

    m1.solve()

    I get the following CPLEX error:

    CplexSolverError: CPLEX Error  2004: problem not compatible with Benders.

     

    I know for a fact that the MIP I'm trying to solve allows not one but several Benders Decompositions depending on the variables I leave in the master and what I move down to the subproblems. I checked whether my annotation had had anything to do with the error by setting the benders.strategy to 3 where CPLEX disregards any annotation I may have written and the error persists.

     

    So, I would like to know if the way I'm annotating my variables is correct, if my attempt to solve using Benders is correct and what could be causing the error I'm getting.

     

    Many thanks!

     

    Carlos Casorrán.

     

     

     

     

     

     

     


    #CPLEXOptimizers
    #DecisionOptimization


  • 2.  Re: Benders Decomposition in Python

    Posted 12/14/16 03:48 PM

    The documentation for CPXERR_NOT_FOR_BENDERS (CPLEX Error 2004) says that "Benders algorithm is incompatible with the problem at hand: Ranged constraints, SOS, indicators or other general constraints present."  Do you happen to have any of those types of constraints in your model?

     


    #CPLEXOptimizers
    #DecisionOptimization


  • 3.  Re: Benders Decomposition in Python

    Posted 12/14/16 04:09 PM

    Originally posted by: ccasorra


    Not entirely sure what qualifies as a 'general constraint'....None of the others are present.

     

    C.


    #CPLEXOptimizers
    #DecisionOptimization


  • 4.  Re: Benders Decomposition in Python

    Posted 12/14/16 04:34 PM

    Examples of "general constraints" would be PWL constraints, I guess.  Lazy constraints and user cut constraints are not allowed either.

    And just to be sure, what is the problem type reported by (i.e., if you call it just before m1.solve()):

    print m1.problem_type[m1.get_problem_type()]
    

    Also, do you have any callbacks defined?

     


    #CPLEXOptimizers
    #DecisionOptimization


  • 5.  Re: Benders Decomposition in Python

    Posted 12/14/16 06:08 PM

    Originally posted by: ccasorra


    The get_problem_type() reports the problem is a MILP.

    No pwl constrains, no user cuts and no lazy constraints, just your run of the mill linear inequalities.

    Turns out it was a callback that was interfering all along. I use a MIPInfoCallback to recover the number of nodes explored in the B&B, the LP solution and the time taken to solve the LP. I don't get why that would stop Benders from working, though...If I don't use the callback, is there another way of retrieving the MIP info I need after a run?

     

    FYI, this is the structure of my callback, 

     

    class Info(MIPInfoCallback):
        num_nodes=-1
        best_OBJ=-1
        MIP_relative_gap=-1
        times_called =0
        LPSol= -1
        FirstT = 1
        stopinc=0
        def __call__(self):
            self.times_called += 1
            self.num_nodes=self.get_num_nodes()
            self.best_OBJ=self.get_best_objective_value()
            self.MIP_relative_gap=self.get_MIP_relative_gap()
            if self.times_called==1 and self.FirstT == 1:
                self.LPSol=self.get_best_objective_value()
                self.stopinc=self.get_time()
                self.FirstT = 0


    #CPLEXOptimizers
    #DecisionOptimization


  • 6.  Re: Benders Decomposition in Python

    Posted 12/14/16 06:34 PM

    Using callbacks with benders is just not supported yet.

    You can get that information via:

    • cplex.solution.progress.get_num_nodes_processed()
    • cplex.solution.MIP.get_best_objective()
    • cplex.solution.MIP.get_mip_relative_gap()
    • cplex.get_time()

    Of course, you don't get the intermediate values, though.

     


    #CPLEXOptimizers
    #DecisionOptimization


  • 7.  Re: Benders Decomposition in Python

    Posted 12/15/16 09:42 AM

    Originally posted by: ccasorra


    Thanks for your answers! I've got my Benders up and running now.

    So, if I'm not allowed to use callbacks, I can still retrieve the number of nodes and the time it takes to solve the integer problem. Great!

    Is there a way of recovering the following parameters? I've looked around without much success.

    • The number of Benders iterations. I'm guessing cplex.solution.progress.get_num_iterations() returns the number of simplex iterations but I'm interested in the number of times I have to go through the master.
    • The time spent solving Master problems and the time spent solving Separation problems. (This I guess is particularly tricky without callbacks...)
    • The number of optimality cuts and feasibility cuts or the number of Benders cuts. This last parameter is returned on screen but how can I query for it?

    C.


    #CPLEXOptimizers
    #DecisionOptimization


  • 8.  Re: Benders Decomposition in Python

    Posted 12/16/16 03:42 AM

    Originally posted by: dominiqs


    Unfortunately, we provide no API to query those pieces of information (and for some, we do not even keep track ourselves).


    #CPLEXOptimizers
    #DecisionOptimization