callback to terminate after a number of same incumbent solution
AnsweredThe problem is solved through column generation, and the subproblem is an MILP. I think that it is a better idea not to solve this MILP until 0.01% mipgap is observed at every iteration. Hence, I wrote a callback for Gurobi to terminate solving this MILP at several different levels of mipgap depending on the reduced costs.
I also want to add in the same callback to terminate solving MILP if the best incumbent solution is not changed, say, for the last 50 iterations, but this didnt work.
Has anybody observed a similar problem? If yes, how can it be solved?
Ebru
-
Hi Ebru,
What do you mean by "it didn't work"? Callback termination is very flexible, and so far, I have not seen any situation where the mechanism didn't provide a good answer for special conditions for terminations. Maybe your code is not compiling? which API are you using?
Best,
Daniel0 -
Hi Daniel,
Thank you for the fast reply.
I am using C API. I copied my callback function. This callback function was aimed to terminate solving an MILP model called pricing_model depending on two cases.
Case 1: If for the last successive 50 iterations, the best incumbent solution is not changed, stop solving the pricing_model.
Case 2: Stop solving pricing_model when the mipgap is 30%, 20%, etc. depending on the reduced costs.
Master_dual_last and iter are passed from the main program. For this callback, Case 2 works exactly as it should.
But Case 1 (stop solving the MILP after observing the same incumbent solution for the last successive 50 iterations) did not work.
So this is the question.
Kind regards
Ebru
int __stdcall
mycallback(GRBmodel *pricing_model,void *cbdata,int where,void *usrdata){struct callback_data *mydata = (struct callback_data *) usrdata;double master_last = mydata->master_dual_last;int call_iter = mydata->iter;double subprob_bnd, best_obj_bnd, old_obj_bnd;int fifty_iterations;if (where == GRB_CB_MIP) {if (call_iter == 0){fifty_iterations = 0;old_obj_bnd = 0.0;}GRBcbget(cbdata, where, GRB_CB_MIP_OBJBST, &best_obj_bnd);GRBcbget(cbdata, where, GRB_CB_MIP_OBJBND, &subprob_bnd);if (old_obj_bnd == best_obj_bnd)fifty_iterations++;elsefifty_iterations = 0;old_obj_bnd = best_obj_bnd;if (fifty_iterations > 50)GRBterminate(pricing_model);if (best_obj_bnd - master_last <= -300000) {if (fabs(best_obj_bnd - subprob_bnd) < 0.3 * fabs(best_obj_bnd))GRBterminate(pricing_model);}else if ((best_obj_bnd - master_last <= -100000) && (best_obj_bnd - master_last > -300000)) {if (fabs(best_obj_bnd - subprob_bnd) < 0.2 * fabs(best_obj_bnd))GRBterminate(pricing_model);}else if ((best_obj_bnd - master_last <= -5000) && (best_obj_bnd - master_last > -100000)) {if (fabs(best_obj_bnd - subprob_bnd) < 0.1 * fabs(best_obj_bnd))GRBterminate(pricing_model);}else {if (fabs(best_obj_bnd - subprob_bnd) < 0.001 * fabs(best_obj_bnd))GRBterminate(pricing_model);}}return 0;}0 -
Hi Ebru,
You are not saving the "fifty_iterations" within your user callback data, so it will never reach to 50, or only because it has an uninitialized initial value..... probably valgrind would catch some of those issues
Daniel
0 -
Hi Daniel,
In fact, fifty_iterations was not initialized at all. I solved the problem, started it in the main program and passed it to the callback function.
Thank you.
Kind regards
Ebru
0 -
Glad to hear that
0
Please sign in to leave a comment.
Comments
5 comments