Decision Optimization

Decision Optimization

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

 View Only

Callback in Bender's decomposition- python

  • 1.  Callback in Bender's decomposition- python

    Posted Fri February 09, 2018 12:40 PM

    Originally posted by: rezir


    I have an optimization model that can be decomposed. The master problem is a MIP and the sub problem is a LP model. I got inspired from the IBM example (bendersatsp) to expand my benders using callback. The only difference is that I need to add optimality cut rather than feasibility cut. Again using the former posts here I did that. According to Bender's algorithm, for adding optimality cut I need to check the stopping condition as well as optimality. This is, if  y is optimal and c'y>z , the optimality cut will be added till c'y=z.

    My problem is that, when I do not consider the stopping condition for some instances I have the optimal solution and the algorithm works well, whereas it could not find the optimal solution in other instances. If I add the stopping condition it cannot find the optimal solution at all. Could you please help me to figure it out. I appreciate that.

    Please find some parts of my code regarding call back and separate function in the following..

    classBendersLazyConsCallback(LazyConstraintCallback):      

        def__call__(self):      

            v       = self.v

            u       = self.u

            z       = self.z

            T       = self.T      

            workerLP = self.workerLP

            boxty = len(u)      

            ite=len(z)     

            sol1 = []

            sol2 = []

            sol3 = []

            sol1= self.get_values(u);

            fori inrange(1, ite+1):

                sol3.append([])

                sol3[i-1]= self.get_values(v[i-1]);           

            sol4=0

            sol4= self.get_values(T);      

            # Benders' cut separation

                      ifworkerLP.separate(sol3, sol1, sol4, v, u, T):

                self.add(constraint = workerLP.cutLhs, sense = "L", rhs = workerLP.cutRhs)

     

     

     

    defseparate(self, vSol,uSol,TSol, v, u, T):

    …………

    …………

     

     

    cpx.solve()

    print("v:",v) # v is a continuous decision variable in the master problem

    print("u:",u) # u is an integer decision variable in the master problem

     

     

    print("T:",T) # T is the dummy decision variable added to the master problem and is the z of the model in the link

    print("w:",w) # w is the c'y of the model in the link

     

    violatedCutFound  = False

    ifcpx.solution.get_status() == cpx.solution.status.optimal and (w >T):

                print("optimum")

        

      

        

                cutVarsList  = []

                cutCoefsList = []

        

                fori initems:

                    fork inboxtypes:

                        cutVarsList.append(v[i-1][k-1])

                fork inboxtypes:

                    cutVarsList.append(u[k-1])                                

                cutVarsList.extend(T)                          

                                

                cutCoefsList=d

                cutCoefsList.append(-1)

                cutLhs = cplex.SparsePair(ind = cutVarsList, val = cutCoefsList)

                    

                self.cutLhs = cutLhs

                self.cutRhs = cutRhs

                violatedCutFound  = True

                print("violatedCutFound ")   

      returnviolatedCutFound

     

     


    #CPLEXOptimizers
    #DecisionOptimization