Skip to main content

Gurobi callback function and performance

Ongoing

Comments

4 comments

  • Tobias Achterberg
    Gurobi Staff Gurobi Staff

    Having an empty callback should not deteriorate performance much. If you are using Python, then of course a callback means that we need to always step into the Python interpreter, but even this shouldn't affect performance significantly, maybe except for corner cases like really small models on which Gurobi processes super many branch-and-bound tree nodes per second.

    While the callback is executed, everything else comes to a halt. So, if you are doing heavy computations inside your callback, then this will slow down the overall process.

    Regards,

    Tobias

     

    0
  • Namrita Varshney
    First Comment

     is it true that Gurobi always executes the callback only after finding the feasible solution?? or it can be the case that during the callback gurobi does not have the complete model solution??

    0
  • Riley Clement
    Gurobi Staff Gurobi Staff

    Hi Namrita,

    No, this is not true.  Please take a look at the following links:

    Callbacks
    Callback Codes
    callback.py

    - Riley

    0
  • Namrita Varshney
    First Comment

    thank you for reply.
    look at the code , I was not able to add   sol = model.cbGetSolution(variables) in callback_tree function, So I created a dictionary to find my solution , 
    it can be the case the the solution gurobi find during this callback , it might not satisfy all the constraint

    def mycallback(model, where):
        if not hasattr(model, '_last_print_time'):
            model._last_print_time = time.time()
            model._last_sol = ""

        if where == GRB.Callback.MIPSOL:
            objVal = model.cbGet(GRB.Callback.MIPSOL_OBJ)
            current_time = time.time()
            if current_time - model._last_print_time >= 10:
                variables = model.getVars()
                sol = model.cbGetSolution(variables)
                variable_dict = {var: value for var,value in zip(variables,sol)}

                root = model._root 
                print_tree(root)            
                print("==================================================")
                print("Hiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii  callback  ")
                listt = set()
                listt = callback_tree(model,root, sol, variable_dict,listt)
                print("==================================================")
                
         
                intermediate_sol ,taut_list,flag =process_intermediat_tree(model,root)
                # print(taut_list)
                
                
                if flag == 1:
                    msg = f"{listt} lazy constraint added "
                    print(msg)
                    lazy_constr = gp.quicksum(model.getVarByName(var) for var in listt) <= len(listt) - 1
                    model.cbLazy(lazy_constr)
                    model._sol = ""
                if intermediate_sol == model._sol and model.RUNTIME > 1500 and current_time - model._last_print_time >= 500 and model._sol != "":
                    print("model._countsol: ",model._countsol)
                    # model._countsol += 1
                    # if model._countsol > 4:
                    print("No change in sol")
                    model.terminate()

                model._last_print_time = current_time
                
                
    def callback_tree(model, root, sol, variable_dict,listt):
        if root is None:
            return listt
        
        value = root.node_number
        print(f"-------------------------------------------------------I am at a node {root.node_number} {root.value}------------------------------")
        # print(f"-------------------------------------------------{variable_dict[model.getVarByName(str(root.value)+str(root.node_number))]}------------------------------")
        flag=0
        for v in decl.all_list:
            varname = str(v) + str(value)
            # print(f"-------------------varname: {varname}-------------------")
            # print(type(varname))      
            var_value = variable_dict[model.getVarByName(varname)]
                
            if var_value ==1:
                flag =1
                print(f" {varname} is true")
                listt.add(varname)
                root.value = v

        if flag==0:
            print(f"Variables not found. {root.node_number}  {root.value}")
            
        listt.update(callback_tree(model, root.left, sol, variable_dict,listt))
        listt.update(callback_tree(model, root.right, sol, variable_dict,listt))
        return listt

    0

Please sign in to leave a comment.