Skip to main content

callback to terminate after a number of same incumbent solution

Answered

Comments

5 comments

  • Daniel Espinoza

    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,
    Daniel

    0
  • Ebru Angun
    Gurobi-versary
    Conversationalist
    Curious

    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++;
    else
    fifty_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
  • Daniel Espinoza

    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
  • Ebru Angun
    Gurobi-versary
    Conversationalist
    Curious

    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
  • Daniel Espinoza

    Glad to hear that

    0

Please sign in to leave a comment.