Skip to main content

callback to terminate after a number of same incumbent solution

Answered

Comments

6 comments

  • Official comment
    Simranjit Kaur
    Gurobi Staff Gurobi Staff
    This post is more than three years old. Some information may not be up to date. For current information, please check the Gurobi Documentation or Knowledge Base. If you need more help, please create a new post in the community forum. Or why not try our AI Gurobot?.
  • 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

Post is closed for comments.