0

I have written a manual benders algorithm on python. I utilize CPLEX to solve both master and subproblems.

My problem is, the algorithm never ends. I debugged and found out that even though it adds a new constraint (I do not know how to see the added constraint, I can only see the number of constraints in the master problem increases), the upper and lower bounds never change, the solutions for the sub and master problems are always the same.

  • Do you see anything extraordinary with the code?

  • Is there a way that CPLEX allow me to see the added constraints while debugging the code?

  • Am I adding the optimality cuts in a wrong way?

  • Is there a more efficient way to solve this problem after splitting the master and subproblems? (I know CPLEX's automatic solver, as far as I know it only solves if you provide the original formulation.)

The code is as follows:

while abs(UB-LB)>8:
    sub.solve()
    sub_obj_value=sub_obj.solution_value
    UB=sub_obj_value
    for j in range(facility):
        u_bar[j]=u[j].solution_value
    master.add_constraint(q <=master.sum(-var[i,j]*u_bar[j]*x[i,j] for i in range(demand) for j in range(facility)), ctname='new constraint')
    master.solve()
    for i in range(demand):
        for j in range(facility):
            x_bar[i,j]=x[i,j].solution_value
    master_obj_value=master_obj.solution_value
    q_value=q.solution_value
    LB=q_value
    iter=iter+1
  • x is the decision variable for the master problem.
  • u is the decision variable for the subproblem.
  • q is the variable for the optimality cut in the master problem.
  • var is a parameter.

Btw, code is not quite efficient. If you have any suggestions on that too, I'd love to hear.

Edit:

Objective of the Subproblem:

sub_obj = sub.sum((var[i,j]*x_bar[i,j]*u[j] for i in range(demand) for j in range(facility)))
sub.set_objective("max", sub_obj)
diabolik
  • 55
  • 6
  • 1
    You need to update the sub-problem at some point... And to check for its feasibility or not depending on your program. Currently you just always run the same sub-problem so you always generate the same cut so you're simply adding an identical constraint at each loop. – Holt Dec 07 '22 at 17:16
  • @Holt thank you so much for the comment. I added the objective function of the subproblem to the main post. That is the only thing that is affected by the master problem, subproblem constraints do not involve master problem's variables. Shouldn't it be updated as I'm updating the x_bar values after each time I solve the master problem? – diabolik Dec 07 '22 at 18:09
  • Ok, I was able to solve the problem by moving the objective of the subproblem inside the while loop. It solves the problem but I think it became really inefficient. Do you have any ideas to make it more efficient or do you know of any other ways? @Holt – diabolik Dec 07 '22 at 18:42
  • 1
    You do need to update the dual sub-problem objective at each loop, Because you change `x_bar` does not mean the objective is automatically updated - CPLEX makes its own copy of the expression. What do you mean by inefficient? It takes a lots of step to solve? If so, you can try improving your master by adding extra constraints that might be relevant. Then, docplex has a lot of overhead when solving, so writing your own Benders with docplex will never be *that* efficient. – Holt Dec 08 '22 at 08:06

0 Answers0