#p, cd, cdk, sk = dg.ins_k(10, 100) # (ni,nk,randomseed*) import data_generator0 as dg0 data = dg0.data_gen(6, 30, 1) p, cd, cdk, sk = data.data() from gurobipy import * import time # Number of nodes ni = len(cd) nk = len(cdk) # weights of two stages a1 = 0.5 a2 = 1 - a1 start_time = time.time() TSRFLP = mr.rflp(p, ni, nk, a1, a2, cd, cdk, sk) # primal sub problem TSRFLP.dual = 0 TSRFLP.params_tuneup() # ----------Benders' Decompisition---------- iteration = 0 gap = 1 stop = 1e-5 TSRFLP.master() TSRFLP.master_model.params.OutputFlag = 0 TSRFLP.sub_model.params.OutputFlag = 0 while TSRFLP.gap >= stop: if iteration != 0: TSRFLP.update_master() #filename = ''.join(['.\model\master(',str(iteration),').lp']) # TSRFLP.master_model.write(filename)
def bra_cut(p, cd, cdk, sk, a1, tl_total, tl_node, branch_step): convergence = [] # Number of nodes ni = len(cd) nk = len(cdk) # weights of two stages a2 = 1 - a1 try: def mycallback(model, where): # callback fuction: benders cut & integer cut # time1 = time.time() if where == GRB.Callback.MIP: if TSRFLP.LB_terminate == 1 and TSRFLP.LB_branch == 0: if time.time() - LB_time >= tl_node: model.terminate() if TSRFLP.LB_branch == 1: objbst = model.cbGet(GRB.Callback.MIP_OBJBST) objbnd = model.cbGet(GRB.Callback.MIP_OBJBND) if objbst < 1e10: convergence.append( [objbst, objbnd, time.time() - start_time]) if time.time() - start_time >= 1000: # Stop criteria model.terminate() if where == GRB.Callback.MIPSOL: nodecnt = model.cbGet(GRB.Callback.MIPSOL_NODCNT) objbnd = model.cbGet(GRB.Callback.MIPSOL_OBJBND) vals = model.cbGetSolution(model._vars) TSRFLP.value_y = vals[-2 - ni:-2] if TSRFLP.warm == 'over': TSRFLP.value_y = [round(x) for x in TSRFLP.value_y ] # make sure y are binary TSRFLP.value_omega = vals[-1] if nodecnt > 0 and TSRFLP.LB_terminate == 0: # LB right after root node TSRFLP.LB_terminate = 1 model.terminate() if TSRFLP.value_y not in TSRFLP.tabu: # save best incumbent TSRFLP.tabu.append(TSRFLP.value_y) TSRFLP.update_sub_dual(callback=1) TSRFLP.sub_dual.optimize() max_Lk = TSRFLP.worst_scenario() if max_Lk[ 0] - TSRFLP.value_omega >= 1e-4: # ----benders cut---- TSRFLP.update_multiple_scenario() else: # ----integer cut---- TSRFLP.update_sub(callback=1) time_sub = time.time() TSRFLP.sub_model.optimize() TSRFLP.worst_scenario(1) # calculate max L3 TSRFLP.gap_calculation(1) # calculate int_gap if TSRFLP.int_gap >= 1e-4: # cut incumbent solution TSRFLP.update_integer_cut() model.cbLazy(TSRFLP.omega >= TSRFLP.integer_cut) if where == GRB.Callback.MESSAGE: # Record lazy constraints if TSRFLP.LB_branch == 1: msg = model.cbGet(GRB.Callback.MSG_STRING) cutname = 'Lazy constraints' if cutname in msg: TSRFLP.num_cut += int(msg[20:-1]) TSRFLP = mr.rflp(p, ni, nk, a1, a2, cd, cdk, sk) # instantiate class # setting algorithm environment TSRFLP.dual = 1 TSRFLP.intSP = 1.0 TSRFLP.lift = 0 TSRFLP.zero_half = 0 gap = 1 # # initailization TSRFLP.dual_sub(callback=1) TSRFLP.sub(callback=1) TSRFLP.warm_start(1) # 1:no warm start 0: warm start TSRFLP.params_tuneup() start_time = time.time() # set initail time TSRFLP.master_model._vars = TSRFLP.master_model.getVars() TSRFLP.master_model.Params.lazyConstraints = 1 TSRFLP.master_model.optimize(mycallback) # terminate after root node vn_time = time.time() Branching_record = [1e6, []] # best objval; best solution; # Branching while time.time( ) - vn_time < tl_total / 2: # VNSB total time Limits; value_y change within callback LB_time = time.time() # time Limits for one neighbourhood TSRFLP.add_LB(branch_step) TSRFLP.master_model.optimize(mycallback) best_incumbent = [] if TSRFLP.master_model.Objval < Branching_record[0]: Vars = TSRFLP.master_model.getVars() for n in Vars: best_incumbent.append(n.x) Branching_record = [TSRFLP.master_model.Objval, best_incumbent] TSRFLP.master_model.remove(TSRFLP.master_model.getConstrs()[-1]) TSRFLP.master_model.remove(TSRFLP.master_model.getConstrs()[-2]) # Proximity search pr_time = time.time() impro = 0.1 while time.time() - pr_time < tl_total / 2: LB_time = time.time() TSRFLP.add_proximity(Branching_record, 1 - impro) TSRFLP.master_model.optimize(mycallback) if TSRFLP.master_model.Status in [2, 11]: # optimal or interrupted best_incumbent = [] obj_now = TSRFLP.a1 * TSRFLP.L.x + TSRFLP.a2 * TSRFLP.omega.x if obj_now < Branching_record[0]: print(obj_now) Vars = TSRFLP.master_model.getVars() for n in Vars: best_incumbent.append(n.x) Branching_record = [obj_now, best_incumbent] elif TSRFLP.master_model.Status in [3, 4, 5]: #infeasible impro = impro / 2 TSRFLP.master_model.remove(TSRFLP.master_model.getConstrs()[-1]) TSRFLP.LB_branch = 1 TSRFLP.remove_proximity() for x in TSRFLP.LB_cuts: TSRFLP.master_model.addConstr(TSRFLP.omega >= x) TSRFLP.master_model.getConstrs()[-1].Lazy = 1 TSRFLP.set_initial(Branching_record[1]) TSRFLP.master_model.optimize(mycallback) # final optimization except GurobiError as e: print('Error code ' + str(e.errno) + ": " + str(e)) except AttributeError: print('Encountered an attribute error') runtime = round((time.time() - start_time), 2) if TSRFLP.master_model.Status == 2: TSRFLP.opt = 1 objval = round(TSRFLP.master_model.Objval, 2) gap = TSRFLP.master_model.MIPGap if abs(gap) <= 1e-5: gap = 0 var_y = [] for j in range(TSRFLP.ni): y_name = ''.join(['y[', str(j), ']']) y_temp = TSRFLP.master_model.getVarByName(y_name) var_y.append(y_temp.x) convergence = [*zip(*convergence)] return var_y, runtime, TSRFLP.num_cut, TSRFLP.opt, objval, gap, convergence, len( TSRFLP.LB_cuts)
def bra_cut(p, cd, cdk, sk, a1, tl_total, tl_node, branch_step): convergence = [] # Number of nodes ni = len(cd) nk = len(cdk) # weights of two stages a2 = 1 - a1 try: def mycallback(model, where): # callback fuction: benders cut & integer cut # time1 = time.time() if where == GRB.Callback.MIP: if TSRFLP.LB_terminate == 1 and TSRFLP.LB_branch == 0: if time.time( ) - LB_time >= tl_node: # time Limits for each model.terminate() if TSRFLP.LB_branch == 1: objbst = model.cbGet(GRB.Callback.MIP_OBJBST) objbnd = model.cbGet(GRB.Callback.MIP_OBJBND) if objbst < 1e10: convergence.append( [objbst, objbnd, time.time() - start_time]) if time.time() - start_time >= 1000: # Stop criteria model.terminate() if where == GRB.Callback.MIPSOL: # Status output nodecnt = model.cbGet(GRB.Callback.MIPSOL_NODCNT) # obj = model.cbGet(GRB.Callback.MIPSOL_OBJ) # solcnt = model.cbGet(GRB.Callback.MIPSOL_SOLCNT) # objbst = model.cbGet(GRB.Callback.MIPSOL_OBJBST) # objbnd = model.cbGet(GRB.Callback.MIPSOL_OBJBND) # gap_mipsol = abs(objbst - objbnd)/(1.0 + abs(objbst)) # print('**** New solution at node %d, obj %g, sol %d, ' # 'gap = %g ****' % (nodecnt, obj, solcnt, gap_mipsol)) # print(nodecnt) vals = model.cbGetSolution(model._vars) TSRFLP.value_y = vals[-2 - ni:-2] # print(TSRFLP.value_y) if TSRFLP.warm == 'over': TSRFLP.value_y = [round(x) for x in TSRFLP.value_y ] # make sure y are binary TSRFLP.value_omega = vals[-1] # Local Branching if nodecnt > 0 and TSRFLP.LB_terminate == 0: # LB right after root node TSRFLP.LB_terminate = 1 model.terminate() elif nodecnt == 0 and TSRFLP.LB_terminate == 0: TSRFLP.LB_value_y.append(TSRFLP.value_y) TSRFLP.LB_omega.append(TSRFLP.value_omega) TSRFLP.update_sub_dual(callback=1) time_subdual = time.time() TSRFLP.sub_dual.optimize() max_Lk = TSRFLP.worst_scenario() # print("DUAL_SUB_callback--- %s seconds ---" % round((time.time() - time_subdual), 2)) if max_Lk[ 0] - TSRFLP.value_omega >= 1e-4: # ----benders cut---- TSRFLP.update_multiple_scenario() # print("callback--- %s seconds ---" % round((time.time() - time1), 2)) else: # ----integer cut---- TSRFLP.update_sub(callback=1) time_sub = time.time() TSRFLP.sub_model.optimize() # print("PRIMAL_SUB_callback--- %s seconds ---" % round((time.time() - time_sub), 2)) TSRFLP.worst_scenario(1) # calculate max L3 TSRFLP.gap_calculation(1) # calculate int_gap # print('----Integer gap:',TSRFLP.int_gap) if TSRFLP.int_gap >= 1e-4: # cut incumbent solution TSRFLP.update_integer_cut() model.cbLazy(TSRFLP.omega >= TSRFLP.integer_cut) if where == GRB.Callback.MESSAGE: # Record lazy constraints # Message callback if TSRFLP.LB_branch == 1: msg = model.cbGet(GRB.Callback.MSG_STRING) cutname = 'Lazy constraints' if cutname in msg: TSRFLP.num_cut += int(msg[20:-1]) # print(time.time() - start_time) TSRFLP = mr.rflp(p, ni, nk, a1, a2, cd, cdk, sk) # instantiate class # setting algorithm environment TSRFLP.dual = 1 TSRFLP.intSP = 1.0 TSRFLP.lift = 0 TSRFLP.zero_half = 0 # gap = 1 # # stop = 1e-5 # build = time.time() # TSRFLP.master() # needed when .warm_start is turned off # print("BUILDING MASTER--- %s seconds ---" % round((time.time() - build), 2)) # build = time.time() TSRFLP.dual_sub(callback=1) # print("BUILDING SUBDUAL--- %s seconds ---" % round((time.time() - build), 2)) # build = time.time() TSRFLP.sub(callback=1) # print("BUILDING SUB--- %s seconds ---" % round((time.time() - build), 2)) # warm_t = time.time() TSRFLP.warm_start(1) # 1:no warm start 0: warm start # print("Warm time %s seconds" % round((time.time() - warm_t), 2)) TSRFLP.params_tuneup() # set initail time start_time = time.time() # TSRFLP.master_model._lastnode = -GRB.INFINITY TSRFLP.master_model._vars = TSRFLP.master_model.getVars() TSRFLP.master_model.Params.lazyConstraints = 1 # # while TSRFLP.LB_terminate == 0: # TSRFLP.master_model.optimize(callback_LB) # TSRFLP.master_model.optimize(mycallback) # terminate after root node # TSRFLP.LB_value_y = list(set(TSRFLP.LB_value_y)) LB_time0 = time.time() for n in range(len(TSRFLP.LB_value_y)): if time.time() - LB_time0 > tl_total: break LB_time = time.time() TSRFLP.value_y = TSRFLP.LB_value_y[n] TSRFLP.value_omega = TSRFLP.LB_omega[n] TSRFLP.add_LB(branch_step) TSRFLP.master_model.optimize(mycallback) # remove Hanmming constraints TSRFLP.master_model.remove(TSRFLP.master_model.getConstrs()[-1]) TSRFLP.master_model.remove(TSRFLP.master_model.getConstrs()[-2]) TSRFLP.LB_branch = 1 # add all lazy cuts # print('Cuts to be added: ',len(TSRFLP.LB_cuts)) for x in TSRFLP.LB_cuts: TSRFLP.master_model.addConstr(TSRFLP.omega >= x) TSRFLP.master_model.getConstrs()[-1].Lazy = 1 # final optimization TSRFLP.master_model.optimize(mycallback) except GurobiError as e: print('Error code ' + str(e.errno) + ": " + str(e)) except AttributeError: print('Encountered an attribute error') # TSRFLP.error_check() # print("--- %s seconds ---" % round((time.time() - start_time), 2)) # OUTPUT runtime = round((time.time() - start_time), 2) if TSRFLP.master_model.Status == 2: TSRFLP.opt = 1 objval = round(TSRFLP.master_model.Objval, 2) gap = TSRFLP.master_model.MIPGap if abs(gap) <= 1e-5: gap = 0 var_y = [] for j in range(TSRFLP.ni): y_name = ''.join(['y[', str(j), ']']) y_temp = TSRFLP.master_model.getVarByName(y_name) var_y.append(y_temp.x) convergence = [*zip(*convergence)] return var_y, runtime, TSRFLP.num_cut, TSRFLP.opt, objval, gap, convergence
def benders_deco(Time_Limit, p, cd, cdk, sk, a1): convergence = [] # Number of nodes ni = len(cd) nk = len(cdk) # weights of two stages a2 = 1 - a1 start_time = time.time() TSRFLP = mr.rflp(p, ni, nk, a1, a2, cd, cdk, sk) #dual sub problem TSRFLP.dual = 1 # for dual sub problem TSRFLP.params_tuneup() TSRFLP.intSP = 1 #!!BINARY subproblem variable # ----------Benders' Decompisition---------- iteration = 0 stop = 1e-5 TSRFLP.master() TSRFLP.master_model.params.OutputFlag = 0 while abs(TSRFLP.gap) >= stop: if iteration != 0: TSRFLP.update_master() time_master = time.time() TSRFLP.master_model.optimize() if iteration == 0: TSRFLP.dual_sub() else: TSRFLP.update_sub_dual() TSRFLP.sub_dual.params.OutputFlag = 0 time_sub = time.time() TSRFLP.sub_dual.optimize() TSRFLP.gap_calculation() TSRFLP.update_status() iteration += 1 runtime = time.time() - start_time if convergence != []: convergence.append([ convergence[-1][0], convergence[-1][1], time.time() - start_time ]) convergence.append([TSRFLP.UB, TSRFLP.LB, runtime]) time_limit = 0 if runtime >= Time_Limit: time_limit = 1 break # ------------Integer cut -------------- if time_limit != 1: # Check optimality with primal SP first TSRFLP.UB = GRB.INFINITY #reset TSRFLP.sub() TSRFLP.sub_model.params.OutputFlag = 0 TSRFLP.sub_model.optimize() TSRFLP.gap_calculation(0, 1) if TSRFLP.gap > 1e-4: TSRFLP.update_integer_cut() TSRFLP.master_model.addConstr(TSRFLP.omega >= TSRFLP.integer_cut) # print('========= Start Integer L-shaped cut ==========') while abs(TSRFLP.gap) > 1e-4 and time_limit != 1: # Integer L-shaped cut TSRFLP.update_integer_cut() TSRFLP.master_model.addConstr(TSRFLP.omega >= TSRFLP.integer_cut) # Benders' cut TSRFLP.update_sub_dual() TSRFLP.sub_dual.optimize() TSRFLP.update_cut() TSRFLP.master_model.addConstr(TSRFLP.omega >= TSRFLP.constr_y) TSRFLP.master_model.optimize() TSRFLP.update_sub(callback=0) TSRFLP.sub_model.optimize() TSRFLP.gap_calculation(0, 1) # calculate gap TSRFLP.update_status() # iteration += 1 runtime = time.time() - start_time convergence.append( [convergence[-1][0], convergence[-1][1], time.time() - start_time]) convergence.append([TSRFLP.UB, TSRFLP.LB, runtime]) if runtime >= Time_Limit: break # print('Optimal Objective Value = ', str(TSRFLP.UB)) # print("--- %s seconds ---" % runtime) if TSRFLP.int_gap == float('inf'): gap = TSRFLP.gap else: gap = TSRFLP.int_gap if abs(gap) <= 1e-5: TSRFLP.opt = 1 gap = 0 objval = round(TSRFLP.UB, 2) convergence = [*zip(*convergence)] runtime = round(runtime, 2) gap = round(gap, 2) return runtime, iteration, TSRFLP.opt, objval, gap, convergence
def bra_cut(p, cd, cdk, sk, a1): # Number of nodes ni = len(cd) nk = len(cdk) # weights of two stages a2 = 1 - a1 try: # callback_time = 0 # callback_num = 0 # Benders_cut_call = 0 # Integer_cut = 0 def mycallback(model, where): if where == GRB.Callback.MIPSOL: TSRFLP.callback_num += 1 print('callback_num: ', TSRFLP.callback_num) time1 = time.time() # status # nodecnt = model.cbGet(GRB.Callback.MIPSOL_NODCNT) # obj = model.cbGet(GRB.Callback.MIPSOL_OBJ) # solcnt = model.cbGet(GRB.Callback.MIPSOL_SOLCNT) # objbst = model.cbGet(GRB.Callback.MIPSOL_OBJBST) # objbnd = model.cbGet(GRB.Callback.MIPSOL_OBJBND) # gap_mipsol = abs(objbst - objbnd)/(1.0 + abs(objbst)) # #print('**** New solution at node %d, obj %g, sol %d, ' # 'gap = %g ****' % (nodecnt, obj, solcnt, gap_mipsol)) vals = model.cbGetSolution(model._vars) TSRFLP.value_y = vals[-2 - ni:-2] TSRFLP.value_y = [round(x) for x in TSRFLP.value_y ] # make sure y are binary TSRFLP.value_omega = vals[-1] TSRFLP.update_sub_dual(callback=1) time_subdual = time.time() TSRFLP.sub_dual.optimize() # In every callback max_Lk = TSRFLP.worst_scenario() print("DUAL_SUB_callback--- %s seconds ---" % round( (time.time() - time_subdual), 2)) if max_Lk[0] - TSRFLP.value_omega >= 1e-4: TSRFLP.update_multiple_scenario() TSRFLP.Benders_cut_call += 1 print('Benders_cut: ', TSRFLP.Benders_cut_call) print('Benders_total:', TSRFLP.Benders_cut) # ------- integer cut -------- else: # TSRFLP.update_sub(callback=1) time_sub = time.time() # TSRFLP.sub_model.optimize() print("PRIMAL_SUB_callback--- %s seconds ---" % round( (time.time() - time_sub), 2)) TSRFLP.worst_scenario(1) # calculate max L3k TSRFLP.gap_calculation(1) # calculate int_gap # print('----Integer gap:',TSRFLP.int_gap) if TSRFLP.int_gap >= 1e-4: # cut incumbent solution TSRFLP.update_integer_cut() model.cbLazy(TSRFLP.omega >= TSRFLP.integer_cut) TSRFLP.Integer_cut += 1 print('Integer_cut: ', TSRFLP.Integer_cut) TSRFLP.callback_time += time.time() - time1 print('total callback time: ', TSRFLP.callback_time) print("callback--- %s seconds ---" % round( (time.time() - time1), 2)) if where == GRB.Callback.MESSAGE: # Message callback msg = model.cbGet(GRB.Callback.MSG_STRING) cutname = 'Lazy constraints' if cutname in msg: TSRFLP.num_cut += int(msg[20:-1]) # print(time.time() - start_time) if time.time() - start_time >= 2000: model.terminate() TSRFLP = mr.rflp(p, ni, nk, a1, a2, cd, cdk, sk) TSRFLP.dual = 1 TSRFLP.intSP = 1 TSRFLP.lift = 0 TSRFLP.zero_half = 0 # -------------------- gap = 1 stop = 1e-5 # build = time.time() TSRFLP.master() # #print("BUILDING MASTER--- %s seconds ---" % round((time.time() - build), 2)) # build = time.time() TSRFLP.dual_sub(callback=1) # #print("BUILDING SUBDUAL--- %s seconds ---" % round((time.time() - build), 2)) # build = time.time() TSRFLP.sub(callback=1) # #print("BUILDING SUB--- %s seconds ---" % round((time.time() - build), 2)) TSRFLP.params_tuneup() # set initail time start_time = time.time() TSRFLP.master_model._lastnode = -GRB.INFINITY TSRFLP.master_model._vars = TSRFLP.master_model.getVars() TSRFLP.master_model.Params.lazyConstraints = 1 # # TSRFLP.warm_start() TSRFLP.master_model.optimize(mycallback) except GurobiError as e: print('Error code ' + str(e.errno) + ": " + str(e)) except AttributeError: print('Encountered an attribute error') # TSRFLP.error_check() #print("--- %s seconds ---" % round((time.time() - start_time), 2)) # OUTPUT runtime = round((time.time() - start_time), 2) if TSRFLP.master_model.Status == 2: TSRFLP.opt = 1 objval = round(TSRFLP.master_model.Objval, 2) gap = TSRFLP.master_model.MIPGap if abs(gap) <= 1e-5: gap = 0 Benders_total = TSRFLP.Benders_cut var_y = [] for j in range(TSRFLP.ni): y_name = ''.join(['y[', str(j), ']']) y_temp = TSRFLP.master_model.getVarByName(y_name) var_y.append(y_temp.x) return var_y, runtime, TSRFLP.num_cut, TSRFLP.opt, objval, gap
def bra_cut(p, cd, cdk, sk, a1, tl_total, tl_node, tl_pr_node, tl_pr_total, branch_step, stop_gap): convergence = [] # Number of nodes ni = len(cd) nk = len(cdk) # weights of two stages a2 = 1 - a1 try: def mycallback(model, where): # callback fuction: benders cut & integer cut if where == GRB.Callback.MIP: if TSRFLP.LB_terminate == 1 and TSRFLP.LB_branch == 0: if TSRFLP.vn_end == 1: if time.time() - pr_node_time >= tl_pr_node: model.terminate() if time.time() - pr_time >= tl_pr_total: model.terminate() TSRFLP.pr_end = 1 else: if time.time() - LB_time >= tl_node: model.terminate() if time.time() - vn_time >= tl_total: model.terminate() TSRFLP.vn_end = 1 objbst = model.cbGet(GRB.Callback.MIP_OBJBST) objbnd = model.cbGet(GRB.Callback.MIP_OBJBND) if time.time() - start_time >= 1000: # Stop criteria model.terminate() if where == GRB.Callback.MIPSOL: nodecnt = model.cbGet(GRB.Callback.MIPSOL_NODCNT) objbst = model.cbGet(GRB.Callback.MIPSOL_OBJBST) objbnd = model.cbGet(GRB.Callback.MIPSOL_OBJBND) vals = model.cbGetSolution(model._vars) TSRFLP.value_y = vals[-3 - ni:-3] if TSRFLP.warm == 'over': TSRFLP.value_y = [round(x) for x in TSRFLP.value_y ] # make sure y are binary TSRFLP.value_omega = vals[-1] if nodecnt > 0 and TSRFLP.LB_terminate == 0: # LB right after root node TSRFLP.LB_terminate = 1 TSRFLP.bestbound = objbnd model.terminate() if TSRFLP.value_y not in TSRFLP.LB_cuts_y: TSRFLP.update_sub_dual(callback=1) TSRFLP.sub_dual.optimize() max_Lk = TSRFLP.worst_scenario() if max_Lk[ 0] - TSRFLP.value_omega >= 1e-4: # ----benders cut---- TSRFLP.update_multiple_scenario() else: # ----integer cut---- TSRFLP.update_sub(callback=1) TSRFLP.sub_model.optimize() TSRFLP.worst_scenario(1) # calculate max L3 TSRFLP.gap_calculation(1) # calculate int_gap if TSRFLP.int_gap >= 1e-4: # cut incumbent solution TSRFLP.update_integer_cut() model.cbLazy(TSRFLP.omega >= TSRFLP.integer_cut) # else: # incumbent has not been cut # if TSRFLP.pr_end == 0 and TSRFLP.vn_end ==1: # if objbst< 1e5: # terninate at hard incumbent # model.terminate() # uncut_value = TSRFLP.a1*vals[-1]+TSRFLP.a2*vals[-2] # if TSRFLP.LB_terminate == 1 and TSRFLP.LB_branch == 0: # if uncut_value <= convergence[-1][0]: # convergence.append([convergence[-1][0],convergence[-1][1],time.time()-start_time]) # convergence.append([uncut_value,TSRFLP.bestbound,time.time()-start_time]) # else: # convergence.append([convergence[-1][0],convergence[-1][1],time.time()-start_time]) # elif TSRFLP.LB_terminate == 0: # if convergence == []: # convergence.append([uncut_value,objbnd,time.time()-start_time]) # else: # if uncut_value <= convergence[-1][0]: # convergence.append([convergence[-1][0],convergence[-1][1],time.time()-start_time]) # convergence.append([uncut_value,objbnd,time.time()-start_time]) # else: # convergence.append([convergence[-1][0],convergence[-1][1],time.time()-start_time]) # elif TSRFLP.LB_branch == 1: # if objbst < 1e10 and objbst <= convergence[-1][0] and objbnd > 0: # convergence.append([convergence[-1][0],convergence[-1][1],time.time()-start_time]) # convergence.append([objbst,objbnd,time.time()-start_time]) # else: # convergence.append([convergence[-1][0],convergence[-1][1],time.time()-start_time]) else: print('sadasdadsasdadasdadsasdadasdadsasd') indices = [ i for i, x in enumerate(TSRFLP.LB_cuts_y) if x == TSRFLP.value_y ] for n in indices: model.cbLazy(TSRFLP.omega >= TSRFLP.LB_cuts[n]) if where == GRB.Callback.MESSAGE: # Record lazy constraints if TSRFLP.LB_branch == 1: msg = model.cbGet(GRB.Callback.MSG_STRING) cutname = 'Lazy constraints' if cutname in msg: TSRFLP.num_cut += int(msg[20:-1]) TSRFLP = mr.rflp(p, ni, nk, a1, a2, cd, cdk, sk) # instantiate class # setting algorithm environment TSRFLP.dual = 1 TSRFLP.intSP = 1.0 TSRFLP.lift = 0 TSRFLP.zero_half = 0 gap = 1 # # initailization TSRFLP.dual_sub(callback=1) TSRFLP.sub(callback=1) TSRFLP.warm_start(1) # 1:no warm start 0: warm start TSRFLP.params_tuneup() start_time = time.time() # set initail time TSRFLP.master_model._vars = TSRFLP.master_model.getVars() TSRFLP.master_model.Params.lazyConstraints = 1 TSRFLP.master_model.optimize(mycallback) # terminate after root node rootval = TSRFLP.master_model.objval Branching_record = [1e6, []] Branching_record, better_sol = TSRFLP.record_best_sol( Branching_record, start_time) TSRFLP.add_LB(Branching_record, branch_step, 1) LB_cut = 2 vn_time = time.time() # Branching sol_count = 0 while TSRFLP.vn_end == 0: # LB_time = time.time() # time Limits for one neighbourhood TSRFLP.master_model.optimize(mycallback) if TSRFLP.master_model.status in [3, 4, 5]: break Branching_record, better_sol = TSRFLP.record_best_sol( Branching_record, start_time) if better_sol == 1: if TSRFLP.master_model.getConstrs()[-1].sense == '<': TSRFLP.master_model.getConstrs()[-1].sense = '>' TSRFLP.add_LB(Branching_record, branch_step) LB_cut += 1 else: sol_count += 1 if TSRFLP.master_model.getConstrs()[-1].rhs < TSRFLP.p * 2: TSRFLP.master_model.getConstrs()[-1].rhs += 2 else: break # if sol_count >= 2: # break for n in range(LB_cut): TSRFLP.master_model.remove(TSRFLP.master_model.getConstrs()[-n - 1]) # Proximity search pr_time = time.time() pr_gap = 1 while TSRFLP.pr_end == 0: pr_node_time = time.time() rhs, soft_rhs = TSRFLP.add_proximity(Branching_record) TSRFLP.master_model.optimize(mycallback) if TSRFLP.master_model.Status in [2, 11]: # optimal or interrupted if TSRFLP.master_model.ObjVal < 1e10: # optimal or feasible best_incumbent = [] obj_now = TSRFLP.a1 * TSRFLP.L.x + TSRFLP.a2 * TSRFLP.omega.x if obj_now < Branching_record[0]: Vars = TSRFLP.master_model.getVars() for n in Vars: best_incumbent.append(n.x) Branching_record = [ obj_now, best_incumbent, time.time() - start_time ] if abs(soft_rhs - obj_now) < 0.01: TSRFLP.bestbound = rhs else: # cannot find feasible solution TSRFLP.pr_end = 1 # stop elif TSRFLP.master_model.Status in [3, 4, 5]: #infeasible TSRFLP.bestbound = Branching_record[0] - (Branching_record[0] - TSRFLP.bestbound) / 4 pr_gap = (Branching_record[0] - TSRFLP.bestbound) / (1 + Branching_record[0]) if pr_gap <= stop_gap: TSRFLP.pr_end = 1 print('++++++++++++++++++++++++++++++++++++++++++++++++++++++++++') print('gap: ', pr_gap, ' UB= ', Branching_record[0], ' LB= ', TSRFLP.bestbound) TSRFLP.master_model.remove(TSRFLP.master_model.getConstrs()[-1]) TSRFLP.master_model.remove(TSRFLP.master_model.getConstrs()[-2]) TSRFLP.remove_proximity() Heu_sol = [ round(Branching_record[0], 2), round(Branching_record[2], 2) ] TSRFLP.LB_branch = 1 for x in TSRFLP.LB_cuts: TSRFLP.master_model.addConstr(TSRFLP.omega >= x) TSRFLP.master_model.getConstrs()[-1].Lazy = 1 if Branching_record[1] != []: TSRFLP.set_initial(Branching_record[1]) # TSRFLP.master_model.addConstr(TSRFLP.a1*TSRFLP.L+TSRFLP.a2*TSRFLP.omega >= TSRFLP.bestbound) #? TSRFLP.master_model.optimize(mycallback) # final optimization except GurobiError as e: print('Error code ' + str(e.errno) + ": " + str(e)) except AttributeError: print('Encountered an attribute error') runtime = round((time.time() - start_time), 2) if TSRFLP.master_model.Status == 2: TSRFLP.opt = 1 objval = round(TSRFLP.master_model.Objval, 2) gap = TSRFLP.master_model.MIPGap if abs(gap) <= 1e-5: gap = 0 var_y = [] for j in range(TSRFLP.ni): y_name = ''.join(['y[', str(j), ']']) y_temp = TSRFLP.master_model.getVarByName(y_name) var_y.append(y_temp.x) convergence = [*zip(*convergence)] gap = round(gap, 2) rootval = round(rootval, 2) if TSRFLP.opt == 1: Heu_sol.append( round((Heu_sol[0] - TSRFLP.master_model.Objval) / (1 + Heu_sol[0]), 2)) else: Heu_sol.append.append(pr_gap) return var_y, runtime, TSRFLP.num_cut, TSRFLP.opt, objval, gap, convergence, len( TSRFLP.LB_cuts), Heu_sol, rootval
def bra_cut(Time_Limit, p, cd, cdk, sk, a1, tl_total, tl_node, tl_pr_node, tl_pr_total, branch_step, stop_gap, pr_terminate, pr_step): convergence = [] Heu_sol = [] # Number of nodes ni = len(cd) nk = len(cdk) # weights of two stages a2 = 1 - a1 try: def mycallback(model, where): # callback fuction: benders cut & integer cut if where == GRB.Callback.MIP: if TSRFLP.LB_terminate == 1 and TSRFLP.LB_branch == 0: if TSRFLP.vn_end == 1: if time.time() - pr_node_time >= tl_pr_node: model.terminate() if time.time() - pr_time >= tl_pr_total: model.terminate() TSRFLP.pr_end = 1 else: if time.time() - LB_time >= tl_node: model.terminate() if time.time() - vn_time >= tl_total: model.terminate() # TSRFLP.vn_end = 1 objbst = model.cbGet(GRB.Callback.MIP_OBJBST) objbnd = model.cbGet(GRB.Callback.MIP_OBJBND) if objbst < 1e10: if TSRFLP.LB_terminate == 1 and TSRFLP.vn_end == 0: # print('22222222222222222') if convergence != [] and objbst <= convergence[-1][0]: convergence.append([ convergence[-1][0], convergence[-1][1], time.time() - start_time ]) convergence.append([ objbst, TSRFLP.bestbound, time.time() - start_time ]) # if TSRFLP.vn_end == 1 and TSRFLP.pr_end == 0: # print('3333333333333333') # print(TSRFLP.a1*TSRFLP.value_L+TSRFLP.a2*TSRFLP.value_omega) # if convergence[-1][0] == 328.49999999999983: # aaa = 1 # obj_now=TSRFLP.a1*TSRFLP.value_L+TSRFLP.a2*TSRFLP.value_omega # if obj_now <= convergence[-1][0]: # convergence.append([convergence[-1][0],convergence[-1][1],time.time()-start_time]) # convergence.append([obj_now,TSRFLP.bestbound,time.time()-start_time]) if TSRFLP.pr_end == 1 and TSRFLP.LB_branch == 1: # print('444444444444444444') if convergence != [] and objbnd >= TSRFLP.bestbound and objbst <= convergence[ -1][0]: convergence.append([ convergence[-1][0], convergence[-1][1], time.time() - start_time ]) convergence.append( [objbst, objbnd, time.time() - start_time]) if TSRFLP.LB_terminate == 0: # print('111111111111111') if convergence != []: convergence.append([ convergence[-1][0], convergence[-1][1], time.time() - start_time ]) convergence.append( [objbst, objbnd, time.time() - start_time]) nodecnt = model.cbGet(GRB.Callback.MIP_NODCNT) if time.time( ) - start_time >= Time_Limit and nodecnt > 0: # Stop criteria model.terminate() if where == GRB.Callback.MIPSOL: nodecnt = model.cbGet(GRB.Callback.MIPSOL_NODCNT) objbst = model.cbGet(GRB.Callback.MIPSOL_OBJBST) objbnd = model.cbGet(GRB.Callback.MIPSOL_OBJBND) vals = model.cbGetSolution(model._vars) TSRFLP.value_y = vals[-3 - ni:-3] if TSRFLP.warm == 'over': # make sure y are binary TSRFLP.value_y = [round(x) for x in TSRFLP.value_y] TSRFLP.value_omega = vals[-1] TSRFLP.value_L = vals[-2] # for recording objval in prox if nodecnt > 200 and TSRFLP.LB_terminate == 0: # LB right after root node TSRFLP.LB_terminate = 1 TSRFLP.bestbound = objbnd model.terminate() if TSRFLP.value_y not in TSRFLP.save_y and TSRFLP.value_y not in TSRFLP.save_y_int: TSRFLP.update_sub_dual(callback=1) TSRFLP.sub_dual.optimize() max_Lk = TSRFLP.worst_scenario() SP_Qk = [ i.x for i in TSRFLP.sub_dual.getVars()[-TSRFLP.nk:] ] save_sub = TSRFLP.get_subdual_vals() TSRFLP.save_max_Lk_DualLP.append( [TSRFLP.value_y, TSRFLP.max_Lk, SP_Qk, save_sub]) TSRFLP.save_y.append(TSRFLP.value_y) if max_Lk[ 0] - TSRFLP.value_omega >= 1e-4: # ----benders cut---- TSRFLP.update_multiple_scenario(SP_Qk) else: # ----integer cut---- TSRFLP.update_sub(callback=1) TSRFLP.sub_model.optimize() TSRFLP.worst_scenario(1) # calculate max L3 TSRFLP.save_max_Lk_SP.append( [TSRFLP.value_y, TSRFLP.max_Lk]) TSRFLP.save_y_int.append(TSRFLP.value_y) TSRFLP.gap_calculation(1) # calculate int_gap if TSRFLP.int_gap >= 1e-4: TSRFLP.update_integer_cut() model.cbLazy(TSRFLP.omega >= TSRFLP.integer_cut) else: if TSRFLP.pr_end == 0 and TSRFLP.vn_end == 1: if objbst < pr_terminate: # terninate at hard incumbent TSRFLP.pr_end = 1 # model.terminate() obj_now = TSRFLP.a1 * TSRFLP.value_L + TSRFLP.a2 * TSRFLP.value_omega if obj_now <= convergence[-1][0]: convergence.append([ convergence[-1][0], convergence[-1][1], time.time() - start_time ]) convergence.append([ obj_now, TSRFLP.bestbound, time.time() - start_time ]) if obj_now <= TSRFLP.Branching_record[0]: TSRFLP.Branching_record = [ obj_now, vals, time.time() - start_time ] else: save_index = [ (i, x.index(TSRFLP.value_y)) for i, x in enumerate(TSRFLP.save_max_Lk_DualLP) if TSRFLP.value_y in x ] # ----benders cut---- if TSRFLP.save_max_Lk_DualLP[save_index[0][0]][1][ 0] - TSRFLP.value_omega >= 1e-4: TSRFLP.update_multiple_scenario( TSRFLP.save_max_Lk_DualLP[save_index[0][0]][2], TSRFLP.save_max_Lk_DualLP[save_index[0][0]][3]) else: save_index = [ (i, x.index(TSRFLP.value_y)) for i, x in enumerate(TSRFLP.save_max_Lk_SP) if TSRFLP.value_y in x ] if save_index != []: if TSRFLP.save_max_Lk_SP[save_index[0][0]][1][ 0] - TSRFLP.value_omega >= 1e-4: TSRFLP.update_integer_cut( 0, TSRFLP.save_max_Lk_SP[save_index[0][0]][1]) model.cbLazy( TSRFLP.omega >= TSRFLP.integer_cut) else: TSRFLP.update_sub(callback=1) TSRFLP.sub_model.optimize() TSRFLP.worst_scenario(1) # calculate max L3 TSRFLP.save_max_Lk_SP.append( [TSRFLP.value_y, TSRFLP.max_Lk]) TSRFLP.save_y_int.append(TSRFLP.value_y) TSRFLP.gap_calculation(1) # calculate int_gap if TSRFLP.int_gap >= 1e-4: TSRFLP.update_integer_cut() model.cbLazy( TSRFLP.omega >= TSRFLP.integer_cut) else: if TSRFLP.pr_end == 0 and TSRFLP.vn_end == 1: if objbst < pr_terminate: # terninate at hard/soft incumbent TSRFLP.pr_end = 1 # model.terminate() obj_now = TSRFLP.a1 * TSRFLP.value_L + TSRFLP.a2 * TSRFLP.value_omega if obj_now <= convergence[-1][0]: convergence.append([ convergence[-1][0], convergence[-1][1], time.time() - start_time ]) convergence.append([ obj_now, TSRFLP.bestbound, time.time() - start_time ]) if obj_now <= TSRFLP.Branching_record[0]: TSRFLP.Branching_record = [ obj_now, vals, time.time() - start_time ] if where == GRB.Callback.MESSAGE: # Record lazy constraints if TSRFLP.LB_branch == 1: msg = model.cbGet(GRB.Callback.MSG_STRING) cutname = 'Lazy constraints' if cutname in msg: TSRFLP.num_cut += int(msg[20:-1]) TSRFLP = mr.rflp(p, ni, nk, a1, a2, cd, cdk, sk) # instantiate class # setting algorithm environment TSRFLP.dual = 1 TSRFLP.intSP = 1.0 TSRFLP.lift = 0 TSRFLP.zero_half = 0 gap = 1 # initailization TSRFLP.dual_sub(callback=1) TSRFLP.sub(callback=1) TSRFLP.warm_start(1) # 1:no warm start 0: warm start TSRFLP.params_tuneup() start_time = time.time() # set initail time TSRFLP.master_model._vars = TSRFLP.master_model.getVars() TSRFLP.master_model.Params.lazyConstraints = 1 TSRFLP.master_model.optimize(mycallback) # terminate after root node if TSRFLP.master_model.status == 2: TSRFLP.LB_terminate = 1 TSRFLP.master_model.addConstr( TSRFLP.a1 * TSRFLP.L + TSRFLP.a2 * TSRFLP.omega >= TSRFLP.bestbound) rootval = TSRFLP.master_model.objval TSRFLP.Branching_record = [1e6, []] TSRFLP.Branching_record, better_sol, convergence, _ = TSRFLP.record_best_sol( TSRFLP.Branching_record, start_time, convergence) TSRFLP.add_LB(TSRFLP.Branching_record, branch_step, 1) LB_cut = 2 vn_time = time.time() LB_time = 0 # Branching while TSRFLP.vn_end == 0 and tl_total != 0: LB_time = time.time() # time Limits for one neighbourhood TSRFLP.master_model.optimize(mycallback) if TSRFLP.master_model.status in [3, 4, 5]: TSRFLP.vn_end = 1 break if TSRFLP.master_model.status in [2, 11]: TSRFLP.Branching_record, better_sol, convergence, Reverse_record = TSRFLP.record_best_sol( TSRFLP.Branching_record, start_time, convergence) if better_sol == 1: TSRFLP.reverse_LB(Reverse_record, branch_step, better_sol=1) branch_step = 2 TSRFLP.add_LB(TSRFLP.Branching_record, branch_step) # LB_cut += 1 # print('*********************','++better_sol++',branch_step,'incumbent',TSRFLP.Branching_record[0],'last one',Reverse_record[0],'*********************') else: TSRFLP.vn_end = 1 break for n in range(LB_cut): TSRFLP.master_model.remove(TSRFLP.master_model.getConstrs()[-n - 1]) if tl_total == 0: TSRFLP.vn_end = 1 # Proximity search pr_time = time.time() pr_gap = 1 while TSRFLP.pr_end == 0 and tl_pr_total != 0: pr_node_time = time.time() rhs, soft_rhs = TSRFLP.add_proximity(TSRFLP.Branching_record, pr_step) TSRFLP.master_model.optimize(mycallback) if TSRFLP.master_model.Status in [2, 11]: # optimal or interrupted if TSRFLP.master_model.ObjVal < 1e10: # optimal or feasible best_incumbent = [] obj_now = TSRFLP.a1 * TSRFLP.L.x + TSRFLP.a2 * TSRFLP.omega.x if obj_now < TSRFLP.Branching_record[0]: Vars = TSRFLP.master_model.getVars() for n in Vars: best_incumbent.append(n.x) TSRFLP.Branching_record = [ obj_now, best_incumbent, time.time() - start_time ] if abs(soft_rhs - obj_now) < abs( rhs - obj_now) and TSRFLP.master_model.Status == 2: TSRFLP.bestbound = rhs convergence.append([ convergence[-1][0], convergence[-1][1], time.time() - start_time ]) convergence.append([ TSRFLP.Branching_record[0], TSRFLP.bestbound, time.time() - start_time ]) else: # cannot find feasible solution if TSRFLP.master_model.ObjBound > 1e5: TSRFLP.bestbound = rhs TSRFLP.pr_end = 1 # stop if TSRFLP.master_model.Status in [3, 4, 5]: # infeasible TSRFLP.bestbound = soft_rhs TSRFLP.pr_end = 1 # pr_gap = (TSRFLP.Branching_record[0] - TSRFLP.bestbound) / (1 + TSRFLP.Branching_record[0]) if pr_gap <= stop_gap: TSRFLP.pr_end = 1 # print('++++++++++++++++++++++++++++++++++++++++++++++++++++++++++') # print('gap: ', pr_gap, ' UB= ', # TSRFLP.Branching_record[0], ' LB= ', TSRFLP.bestbound) TSRFLP.master_model.remove(TSRFLP.master_model.getConstrs()[-1]) TSRFLP.master_model.remove(TSRFLP.master_model.getConstrs()[-2]) TSRFLP.remove_proximity() if tl_pr_total == 0: TSRFLP.pr_end = 1 for n in range(len(convergence)): if abs(TSRFLP.Branching_record[0] - convergence[n][0]) <= 1e-5: Heu_sol = [ round(TSRFLP.Branching_record[0], 2), round(convergence[n][2], 2) ] break TSRFLP.LB_branch = 1 for x in TSRFLP.LB_cuts: TSRFLP.master_model.addConstr(TSRFLP.omega >= x) TSRFLP.master_model.update() for n in range(len(TSRFLP.LB_cuts)): TSRFLP.master_model.getConstrs()[-1 - n].Lazy = 1 TSRFLP.master_model.update() if TSRFLP.Branching_record[1] != []: TSRFLP.set_initial(TSRFLP.Branching_record[1]) TSRFLP.master_model.addConstr( TSRFLP.a1 * TSRFLP.L + TSRFLP.a2 * TSRFLP.omega >= TSRFLP.bestbound) TSRFLP.master_model.optimize(mycallback) # final optimization except GurobiError as e: print('Error code ' + str(e.errno) + ": " + str(e)) except AttributeError: print('Encountered an attribute error') runtime = round((time.time() - start_time), 2) if TSRFLP.master_model.Status == 2: TSRFLP.opt = 1 convergence.append(convergence[-1]) convergence[-1][1] = convergence[-1][0] objval = round(TSRFLP.master_model.Objval, 2) gap = TSRFLP.master_model.MIPGap if abs(gap) <= 1e-5: gap = 0 var_y = [] if objval < 1e10: # prevent infeasible for j in range(TSRFLP.ni): y_name = ''.join(['y[', str(j), ']']) y_temp = TSRFLP.master_model.getVarByName(y_name) var_y.append(y_temp.x) # convergence = [*zip(*convergence)] gap = round(gap, 2) rootval = round(rootval, 2) Heu_sol.append( round((Heu_sol[0] - TSRFLP.master_model.Objval) / (1 + Heu_sol[0]), 2)) return var_y, runtime, TSRFLP.num_cut, TSRFLP.opt, objval, gap, convergence, len( TSRFLP.LB_cuts), Heu_sol, rootval
def bra_cut(p, cd, cdk, sk, a1, tl_total, branch_step): convergence = [] # Number of nodes ni = len(cd) nk = len(cdk) # weights of two stages a2 = 1 - a1 try: def mycallback(model, where): # callback fuction: benders cut & integer cut if where == GRB.Callback.MIP: if TSRFLP.LB_terminate == 1 and TSRFLP.LB_branch == 0: if time.time() - start_time >= tl_total: # time Limits model.terminate() if TSRFLP.LB_branch == 1: objbst = model.cbGet(GRB.Callback.MIP_OBJBST) objbnd = model.cbGet(GRB.Callback.MIP_OBJBND) convergence.append( [objbst, objbnd, time.time() - start_time]) if time.time() - start_time >= 1000: # Stop criteria model.terminate() if where == GRB.Callback.MIPSOL: # Status output nodecnt = model.cbGet(GRB.Callback.MIPSOL_NODCNT) vals = model.cbGetSolution(model._vars) TSRFLP.value_y = vals[-3 - ni:-3] if TSRFLP.warm == 'over': TSRFLP.value_y = [round(x) for x in TSRFLP.value_y ] # make sure y are binary TSRFLP.value_omega = vals[-1] # Local Branching if nodecnt > 0 and TSRFLP.LB_terminate == 0: # LB right after root node TSRFLP.LB_terminate = 1 model.terminate() TSRFLP.update_sub_dual(callback=1) time_subdual = time.time() TSRFLP.sub_dual.optimize() max_Lk = TSRFLP.worst_scenario() if max_Lk[ 0] - TSRFLP.value_omega >= 1e-4: # ----benders cut---- TSRFLP.update_multiple_scenario() else: # ----integer cut---- TSRFLP.update_sub(callback=1) time_sub = time.time() TSRFLP.sub_model.optimize() TSRFLP.worst_scenario(1) # calculate max L3 TSRFLP.gap_calculation(1) # calculate int_gap if TSRFLP.int_gap >= 1e-4: # cut incumbent solution TSRFLP.update_integer_cut() model.cbLazy(TSRFLP.omega >= TSRFLP.integer_cut) if where == GRB.Callback.MESSAGE: # Record lazy constraints # Message callback if TSRFLP.LB_branch == 1: msg = model.cbGet(GRB.Callback.MSG_STRING) cutname = 'Lazy constraints' if cutname in msg: TSRFLP.num_cut += int(msg[20:-1]) TSRFLP = mr.rflp(p, ni, nk, a1, a2, cd, cdk, sk) # instantiate class # setting algorithm environment TSRFLP.dual = 1 TSRFLP.intSP = 1.0 TSRFLP.lift = 0 TSRFLP.zero_half = 0 # gap = 1 # TSRFLP.dual_sub(callback=1) TSRFLP.sub(callback=1) TSRFLP.warm_start(1) # 1:no warm start 0: warm start TSRFLP.params_tuneup() start_time = time.time() TSRFLP.master_model._vars = TSRFLP.master_model.getVars() TSRFLP.master_model.Params.lazyConstraints = 1 TSRFLP.master_model.optimize(mycallback) # terminate after root node Branching_record = [1e6, []] Branching_record, better_sol = TSRFLP.record_best_sol(Branching_record) LB_total_time = time.time() TSRFLP.add_LB(branch_step) while time.time() - LB_total_time < 2000: # tl_total TSRFLP.master_model.optimize(mycallback) Branching_record, better_sol = TSRFLP.record_best_sol( Branching_record) if TSRFLP.master_model.Status in [2]: branch_step += 2 # TSRFLP.master_model.getConstrs()[-2].rhs = branch_step - 2 # TSRFLP.master_model.getConstrs()[-1].rhs = branch_step # print('+++++++++++++++++branch_step: ',branch_step) if branch_step > TSRFLP.p * 2 or TSRFLP.master_model.Status in [ 11 ]: break TSRFLP.master_model.remove(TSRFLP.master_model.getConstrs()[-1]) TSRFLP.master_model.remove(TSRFLP.master_model.getConstrs()[-2]) TSRFLP.LB_branch = 1 for x in TSRFLP.LB_cuts: TSRFLP.master_model.addConstr(TSRFLP.omega >= x) TSRFLP.master_model.getConstrs()[-1].Lazy = 1 TSRFLP.set_initial(Branching_record[1]) TSRFLP.master_model.optimize(mycallback) # final optimization except GurobiError as e: print('Error code ' + str(e.errno) + ": " + str(e)) except AttributeError: print('Encountered an attribute error') # TSRFLP.error_check() # OUTPUT runtime = round((time.time() - start_time), 2) if TSRFLP.master_model.Status == 2: TSRFLP.opt = 1 objval = round(TSRFLP.master_model.Objval, 2) gap = TSRFLP.master_model.MIPGap if abs(gap) <= 1e-5: gap = 0 var_y = [] for j in range(TSRFLP.ni): y_name = ''.join(['y[', str(j), ']']) y_temp = TSRFLP.master_model.getVarByName(y_name) var_y.append(y_temp.x) convergence = [*zip(*convergence)] return var_y, runtime, TSRFLP.num_cut, TSRFLP.opt, objval, gap, convergence
def bra_cut(Time_Limit, p, cd, cdk, sk, a1): convergence = [] # Number of nodes ni = len(cd) nk = len(cdk) # weights of two stages a2 = 1 - a1 try: def mycallback(model, where): # callback fuction: benders cut & integer cut # time1 = time.time() if where == GRB.Callback.MIP: objbst = model.cbGet(GRB.Callback.MIP_OBJBST) objbnd = model.cbGet(GRB.Callback.MIP_OBJBND) if objbst < 1e10: if convergence != []: if objbst < convergence[-1][0]: convergence.append([ convergence[-1][0], convergence[-1][1], time.time() - start_time ]) convergence.append( [objbst, objbnd, time.time() - start_time]) else: convergence.append( [objbst, objbnd, time.time() - start_time]) else: convergence.append( [objbst, objbnd, time.time() - start_time]) if time.time() - start_time >= Time_Limit: model.terminate() if where == GRB.Callback.MIPSOL: vals = model.cbGetSolution(model._vars) TSRFLP.value_y = vals[-3 - ni:-3] if TSRFLP.warm == 'over': TSRFLP.value_y = [round(x) for x in TSRFLP.value_y ] # make sure y are binary TSRFLP.value_omega = vals[-1] if TSRFLP.value_y not in TSRFLP.save_y and TSRFLP.value_y not in TSRFLP.save_y_int: TSRFLP.update_sub_dual(callback=1) TSRFLP.sub_dual.optimize() max_Lk = TSRFLP.worst_scenario() SP_Qk = [ i.x for i in TSRFLP.sub_dual.getVars()[-TSRFLP.nk:] ] save_sub = TSRFLP.get_subdual_vals() TSRFLP.save_max_Lk_DualLP.append( [TSRFLP.value_y, TSRFLP.max_Lk, SP_Qk, save_sub]) TSRFLP.save_y.append(TSRFLP.value_y) if max_Lk[ 0] - TSRFLP.value_omega >= 1e-4: # ----benders cut---- TSRFLP.update_multiple_scenario(SP_Qk) else: # ----integer cut---- TSRFLP.update_sub(callback=1) TSRFLP.sub_model.optimize() TSRFLP.worst_scenario(1) # calculate max L3 TSRFLP.save_max_Lk_SP.append( [TSRFLP.value_y, TSRFLP.max_Lk]) TSRFLP.save_y_int.append(TSRFLP.value_y) TSRFLP.gap_calculation(1) # calculate int_gap if TSRFLP.int_gap >= 1e-4: TSRFLP.update_integer_cut() model.cbLazy(TSRFLP.omega >= TSRFLP.integer_cut) else: save_index = [ (i, x.index(TSRFLP.value_y)) for i, x in enumerate(TSRFLP.save_max_Lk_DualLP) if TSRFLP.value_y in x ] if TSRFLP.save_max_Lk_DualLP[save_index[0][0]][1][ 0] - TSRFLP.value_omega >= 1e-4: # ----benders cut---- TSRFLP.update_multiple_scenario( TSRFLP.save_max_Lk_DualLP[save_index[0][0]][2], TSRFLP.save_max_Lk_DualLP[save_index[0][0]][3]) else: save_index = [ (i, x.index(TSRFLP.value_y)) for i, x in enumerate(TSRFLP.save_max_Lk_SP) if TSRFLP.value_y in x ] if save_index != []: if TSRFLP.save_max_Lk_SP[save_index[0][0]][1][ 0] - TSRFLP.value_omega >= 1e-4: TSRFLP.update_integer_cut( 0, TSRFLP.save_max_Lk_SP[save_index[0][0]][1]) model.cbLazy( TSRFLP.omega >= TSRFLP.integer_cut) else: TSRFLP.update_sub(callback=1) TSRFLP.sub_model.optimize() TSRFLP.worst_scenario(1) # calculate max L3 TSRFLP.save_max_Lk_SP.append( [TSRFLP.value_y, TSRFLP.max_Lk]) TSRFLP.save_y_int.append(TSRFLP.value_y) TSRFLP.gap_calculation(1) # calculate int_gap if TSRFLP.int_gap >= 1e-4: TSRFLP.update_integer_cut() model.cbLazy( TSRFLP.omega >= TSRFLP.integer_cut) # print('sadasdadsasdadasdadsasdadasdadsasd') # indices = [i for i, x in enumerate(TSRFLP.LB_cuts_y) if x == TSRFLP.value_y] # for n in indices: # model.cbLazy(TSRFLP.omega >= TSRFLP.LB_cuts[n]) if where == GRB.Callback.MESSAGE: # lazy constraints # Message callback msg = model.cbGet(GRB.Callback.MSG_STRING) cutname = 'Lazy constraints' if cutname in msg: TSRFLP.num_cut += int(msg[20:-1]) # print(time.time() - start_time) TSRFLP = mr.rflp(p, ni, nk, a1, a2, cd, cdk, sk) # instantiate class # setting algorithm environment TSRFLP.dual = 1 TSRFLP.intSP = 1.0 TSRFLP.lift = 0 TSRFLP.zero_half = 0 # gap = 1 # # stop = 1e-5 # build = time.time() # TSRFLP.master() # needed when .warm_start is turned off # print("BUILDING MASTER--- %s seconds ---" % round((time.time() - build), 2)) # build = time.time() TSRFLP.dual_sub(callback=1) # print("BUILDING SUBDUAL--- %s seconds ---" % round((time.time() - build), 2)) # build = time.time() TSRFLP.sub(callback=1) # print("BUILDING SUB--- %s seconds ---" % round((time.time() - build), 2)) # warm_t = time.time() TSRFLP.warm_start(1) # print("Warm time %s seconds" % round((time.time() - warm_t), 2)) TSRFLP.params_tuneup() # set initail time start_time = time.time() # TSRFLP.master_model._lastnode = -GRB.INFINITY TSRFLP.master_model._vars = TSRFLP.master_model.getVars() TSRFLP.master_model.Params.lazyConstraints = 1 # TSRFLP.master_model.optimize(mycallback) except GurobiError as e: print('Error code ' + str(e.errno) + ": " + str(e)) except AttributeError: print('Encountered an attribute error') # TSRFLP.error_check() # print("--- %s seconds ---" % round((time.time() - start_time), 2)) # OUTPUT runtime = round((time.time() - start_time), 2) if TSRFLP.master_model.Status == 2: TSRFLP.opt = 1 objval = round(TSRFLP.master_model.Objval, 2) gap = TSRFLP.master_model.MIPGap if abs(gap) <= 1e-5: gap = 0 gap = round(gap, 2) Heu_sol = [] for n in range(len(convergence)): if abs(TSRFLP.master_model.Objval - convergence[n][0]) <= 1e-5: Heu_sol = [ round(TSRFLP.master_model.Objval, 2), round(convergence[n][2], 2) ] break if Heu_sol == []: Heu_sol = [round(TSRFLP.master_model.Objval, 2), Time_Limit] var_y = [] for j in range(TSRFLP.ni): y_name = ''.join(['y[', str(j), ']']) y_temp = TSRFLP.master_model.getVarByName(y_name) var_y.append(y_temp.x) convergence = [*zip(*convergence)] return var_y, runtime, TSRFLP.num_cut, TSRFLP.opt, objval, gap, convergence, Heu_sol
def bra_cut(Time_Limit, p, cd, cdk, sk, a1, tl_total, tl_node, branch_step): convergence = [] # Number of nodes ni = len(cd) nk = len(cdk) # weights of two stages a2 = 1 - a1 try: def mycallback(model, where): # callback fuction: benders cut & integer cut if where == GRB.Callback.MIP: if TSRFLP.LB_terminate == 1 and TSRFLP.LB_branch == 0: if time.time() - LB_time >= tl_node: model.terminate() if time.time() - VN_time >= tl_total: model.terminate() TSRFLP.vn_end = 1 # if TSRFLP.LB_branch == 1: objbst = model.cbGet(GRB.Callback.MIP_OBJBST) objbnd = model.cbGet(GRB.Callback.MIP_OBJBND) if objbst < 1e10: if TSRFLP.LB_terminate == 1 and TSRFLP.vn_end == 0: # print('22222222222222222') if convergence != [] and objbst <= convergence[-1][0]: convergence.append([ convergence[-1][0], convergence[-1][1], time.time() - start_time ]) convergence.append([ objbst, TSRFLP.bestbound, time.time() - start_time ]) if convergence[-1][0] == 742.5: aaa = 1 if TSRFLP.vn_end == 1 and TSRFLP.LB_branch == 1: # print('3333333333333333') if convergence != [] and objbnd >= TSRFLP.bestbound and objbst <= convergence[ -1][0]: convergence.append([ convergence[-1][0], convergence[-1][1], time.time() - start_time ]) convergence.append( [objbst, objbnd, time.time() - start_time]) if convergence[-1][0] == 742.5: aaa = 1 if TSRFLP.LB_terminate == 0: # print('111111111111111') if convergence != []: convergence.append([ convergence[-1][0], convergence[-1][1], time.time() - start_time ]) convergence.append( [objbst, objbnd, time.time() - start_time]) if convergence[-1][0] == 742.5: aaa = 1 nodecnt = model.cbGet(GRB.Callback.MIP_NODCNT) if time.time( ) - start_time >= Time_Limit and nodecnt > 0: # Stop criteria model.terminate() if where == GRB.Callback.MIPSOL: nodecnt = model.cbGet(GRB.Callback.MIPSOL_NODCNT) objbnd = model.cbGet(GRB.Callback.MIPSOL_OBJBND) vals = model.cbGetSolution(model._vars) TSRFLP.value_y = vals[-3 - ni:-3] if TSRFLP.warm == 'over': # make sure y are binary TSRFLP.value_y = [round(x) for x in TSRFLP.value_y] TSRFLP.value_omega = vals[-1] if nodecnt > 200 and TSRFLP.LB_terminate == 0: # LB right after root node TSRFLP.LB_terminate = 1 TSRFLP.bestbound = copy.deepcopy(objbnd) model.terminate() if TSRFLP.value_y not in TSRFLP.save_y and TSRFLP.value_y not in TSRFLP.save_y_int: TSRFLP.update_sub_dual(callback=1) TSRFLP.sub_dual.optimize() max_Lk = TSRFLP.worst_scenario() SP_Qk = [ i.x for i in TSRFLP.sub_dual.getVars()[-TSRFLP.nk:] ] save_sub = TSRFLP.get_subdual_vals() TSRFLP.save_max_Lk_DualLP.append( [TSRFLP.value_y, TSRFLP.max_Lk, SP_Qk, save_sub]) TSRFLP.save_y.append(TSRFLP.value_y) if max_Lk[ 0] - TSRFLP.value_omega >= 1e-4: # ----benders cut---- TSRFLP.update_multiple_scenario(SP_Qk) else: # ----integer cut---- TSRFLP.update_sub(callback=1) TSRFLP.sub_model.optimize() TSRFLP.worst_scenario(1) # calculate max L3 TSRFLP.save_max_Lk_SP.append( [TSRFLP.value_y, TSRFLP.max_Lk]) TSRFLP.save_y_int.append(TSRFLP.value_y) TSRFLP.gap_calculation(1) # calculate int_gap if TSRFLP.int_gap >= 1e-4: TSRFLP.update_integer_cut() model.cbLazy(TSRFLP.omega >= TSRFLP.integer_cut) else: save_index = [ (i, x.index(TSRFLP.value_y)) for i, x in enumerate(TSRFLP.save_max_Lk_DualLP) if TSRFLP.value_y in x ] # ----benders cut---- if TSRFLP.save_max_Lk_DualLP[save_index[0][0]][1][ 0] - TSRFLP.value_omega >= 1e-4: TSRFLP.update_multiple_scenario( TSRFLP.save_max_Lk_DualLP[save_index[0][0]][2], TSRFLP.save_max_Lk_DualLP[save_index[0][0]][3]) else: save_index = [ (i, x.index(TSRFLP.value_y)) for i, x in enumerate(TSRFLP.save_max_Lk_SP) if TSRFLP.value_y in x ] if save_index != []: if TSRFLP.save_max_Lk_SP[save_index[0][0]][1][ 0] - TSRFLP.value_omega >= 1e-4: TSRFLP.update_integer_cut( 0, TSRFLP.save_max_Lk_SP[save_index[0][0]][1]) model.cbLazy( TSRFLP.omega >= TSRFLP.integer_cut) else: TSRFLP.update_sub(callback=1) TSRFLP.sub_model.optimize() TSRFLP.worst_scenario(1) # calculate max L3 TSRFLP.save_max_Lk_SP.append( [TSRFLP.value_y, TSRFLP.max_Lk]) TSRFLP.save_y_int.append(TSRFLP.value_y) TSRFLP.gap_calculation(1) # calculate int_gap if TSRFLP.int_gap >= 1e-4: TSRFLP.update_integer_cut() model.cbLazy( TSRFLP.omega >= TSRFLP.integer_cut) if where == GRB.Callback.MESSAGE: # Record lazy constraints # Message callback if TSRFLP.LB_branch == 1: msg = model.cbGet(GRB.Callback.MSG_STRING) cutname = 'Lazy constraints' if cutname in msg: TSRFLP.num_cut += int(msg[20:-1]) TSRFLP = mr.rflp(p, ni, nk, a1, a2, cd, cdk, sk) # instantiate class # setting algorithm environment TSRFLP.dual = 1 TSRFLP.intSP = 1.0 TSRFLP.lift = 0 TSRFLP.zero_half = 0 # gap = 1 TSRFLP.dual_sub(callback=1) TSRFLP.sub(callback=1) TSRFLP.warm_start(1) # 1:no warm start 0: warm start TSRFLP.params_tuneup() start_time = time.time() # set initail time # TSRFLP.master_model._lastnode = -GRB.INFINITY TSRFLP.master_model._vars = TSRFLP.master_model.getVars() TSRFLP.master_model.Params.lazyConstraints = 1 TSRFLP.master_model.optimize(mycallback) # terminate after root node if TSRFLP.master_model.status == 2: TSRFLP.LB_terminate = 1 TSRFLP.master_model.addConstr( TSRFLP.a1 * TSRFLP.L + TSRFLP.a2 * TSRFLP.omega >= TSRFLP.bestbound) TSRFLP.Branching_record = [1e6, []] TSRFLP.Branching_record, better_sol, convergence, _ = TSRFLP.record_best_sol( TSRFLP.Branching_record, start_time, convergence) TSRFLP.add_LB(TSRFLP.Branching_record, branch_step, 1) LB_cut = 2 VN_time = time.time() while TSRFLP.vn_end == 0 and tl_total != 0: LB_time = time.time() # time Limits for one neighbourhood TSRFLP.master_model.optimize(mycallback) if TSRFLP.vn_end == 1: break if TSRFLP.master_model.status in [3, 4, 5]: if branch_step <= TSRFLP.p * 2 - 2: if branch_step == 2: TSRFLP.reverse_LB(TSRFLP.Branching_record, branch_step) branch_step += 2 TSRFLP.add_LB(TSRFLP.Branching_record, branch_step + 2) # LB_cut += 1 # print('*********************','++first reverse++',branch_step,TSRFLP.Branching_record[0],'*********************') else: TSRFLP.reverse_LB(TSRFLP.Branching_record, branch_step) branch_step += 2 TSRFLP.add_LB(TSRFLP.Branching_record, branch_step + 2) # # print('*********************','++reverse++',branch_step,'incumbent',TSRFLP.Branching_record[0],'*********************') else: TSRFLP.vn_end = 1 break if TSRFLP.master_model.status in [2, 11]: TSRFLP.Branching_record, better_sol, convergence, Reverse_record = TSRFLP.record_best_sol( TSRFLP.Branching_record, start_time, convergence) if better_sol == 1: TSRFLP.reverse_LB(Reverse_record, branch_step, better_sol=1) branch_step = 2 TSRFLP.add_LB(TSRFLP.Branching_record, branch_step) # LB_cut += 1 # print('*********************','++better_sol++',branch_step,'incumbent',TSRFLP.Branching_record[0],'last one',Reverse_record[0],'*********************') else: if branch_step == 2: TSRFLP.reverse_LB(TSRFLP.Branching_record, branch_step) branch_step += 2 TSRFLP.add_LB(TSRFLP.Branching_record, branch_step + 2) # LB_cut += 1 # print('*********************','++first reverse++',branch_step,'incumbent',TSRFLP.Branching_record[0],'*********************') else: TSRFLP.reverse_LB(TSRFLP.Branching_record, branch_step) branch_step += 2 TSRFLP.add_LB(TSRFLP.Branching_record, branch_step + 2) # # print('*********************','++reverse++',branch_step,'incumbent',TSRFLP.Branching_record[0],'*********************') # extract heuristics solution for n in range(len(convergence)): if abs(TSRFLP.Branching_record[0] - convergence[n][0]) <= 1e-5: Heu_sol = [ round(TSRFLP.Branching_record[0], 2), round(convergence[n][2], 2) ] break for n in range(LB_cut): TSRFLP.master_model.remove(TSRFLP.master_model.getConstrs()[-n - 1]) TSRFLP.LB_branch = 1 # for x in TSRFLP.LB_cuts: # TSRFLP.master_model.addConstr(TSRFLP.omega >= x) # TSRFLP.master_model.getConstrs()[-1].Lazy = 1 for x in TSRFLP.LB_cuts: TSRFLP.master_model.addConstr(TSRFLP.omega >= x) TSRFLP.master_model.update() for n in range(len(TSRFLP.LB_cuts)): TSRFLP.master_model.getConstrs()[-1 - n].Lazy = 1 TSRFLP.master_model.update() if TSRFLP.Branching_record[1] != []: TSRFLP.set_initial(TSRFLP.Branching_record[1]) TSRFLP.master_model.addConstr( TSRFLP.a1 * TSRFLP.L + TSRFLP.a2 * TSRFLP.omega >= TSRFLP.bestbound) TSRFLP.master_model.optimize(mycallback) # final optimization except GurobiError as e: print('Error code ' + str(e.errno) + ": " + str(e)) except AttributeError: print('Encountered an attribute error') # TSRFLP.error_check() # OUTPUT runtime = round((time.time() - start_time), 2) if TSRFLP.master_model.Status == 2: TSRFLP.opt = 1 objval = round(TSRFLP.master_model.Objval, 2) gap = TSRFLP.master_model.MIPGap if abs(gap) <= 1e-5: gap = 0 var_y = [] if objval < 1e10: for j in range(TSRFLP.ni): y_name = ''.join(['y[', str(j), ']']) y_temp = TSRFLP.master_model.getVarByName(y_name) var_y.append(y_temp.x) convergence = [*zip(*convergence)] gap = round(gap, 2) Heu_sol.append( round(((Heu_sol[0] - TSRFLP.master_model.Objval) / (1 + Heu_sol[0])), 2)) return var_y, runtime, TSRFLP.num_cut, TSRFLP.opt, objval, gap, convergence, len( TSRFLP.LB_cuts), Heu_sol
def bra_cut(p, cd, cdk, sk, a1): # Number of nodes ni = len(cd) nk = len(cdk) # weights of two stages a2 = 1 - a1 try: # if gap doesn't change for * iterations, add fractional cut def mycallback(model, where): # time1 = time.time() if where == GRB.Callback.MIPSOL: # status # nodecnt = model.cbGet(GRB.Callback.MIPSOL_NODCNT) # obj = model.cbGet(GRB.Callback.MIPSOL_OBJ) # solcnt = model.cbGet(GRB.Callback.MIPSOL_SOLCNT) # objbst = model.cbGet(GRB.Callback.MIPSOL_OBJBST) # objbnd = model.cbGet(GRB.Callback.MIPSOL_OBJBND) # gap_mipsol = abs(objbst - objbnd)/(1.0 + abs(objbst)) # #print('**** New solution at node %d, obj %g, sol %d, ' # 'gap = %g ****' % (nodecnt, obj, solcnt, gap_mipsol)) vals = model.cbGetSolution(model._vars) TSRFLP.value_y = vals[-2 - ni:-2] TSRFLP.value_omega = vals[-1] TSRFLP.update_sub_dual(callback=1) # time_subdual = time.time() TSRFLP.sub_dual.optimize() # #print("SUB_callback--- %s seconds ---" % round((time.time() - time_subdual), 2)) TSRFLP.update_multiple_scenario() # #print("callback--- %s seconds ---" % round((time.time() - time1), 2)) if where == GRB.Callback.MESSAGE: # Message callback msg = model.cbGet(GRB.Callback.MSG_STRING) cutname = 'Lazy constraints' if cutname in msg: TSRFLP.num_cut += float(msg[-2]) if time.time() - start_time >= 2000: model.terminate() def mycallback_int(model, where): if where == GRB.Callback.MIPSOL: # status nodecnt = model.cbGet(GRB.Callback.MIPSOL_NODCNT) obj = model.cbGet(GRB.Callback.MIPSOL_OBJ) solcnt = model.cbGet(GRB.Callback.MIPSOL_SOLCNT) objbst = model.cbGet(GRB.Callback.MIPSOL_OBJBST) objbnd = model.cbGet(GRB.Callback.MIPSOL_OBJBND) gap_mipsol = abs(objbst - objbnd) / (1.0 + abs(objbst)) print('**** New solution at node %d, obj %g, sol %d, ' 'gap = %g ****' % (nodecnt, obj, solcnt, gap_mipsol)) # print(TSRFLP.master_model.MIPGap) vals = model.cbGetSolution(model._vars) TSRFLP.value_y = vals[-2 - ni:-2] TSRFLP.value_omega = vals[-1] # integer l-shaped cut TSRFLP.update_sub(callback=1) TSRFLP.sub_model.optimize() TSRFLP.worst_scenario(1) # calculate max L3 TSRFLP.gap_calculation(1) # calculate int_gap print('----Integer gap:', TSRFLP.int_gap) if TSRFLP.int_gap >= 1e-4: # cut incumbent solution TSRFLP.update_integer_cut() model.cbLazy(TSRFLP.omega >= TSRFLP.integer_cut) # optimality cut (Benders' cut) TSRFLP.update_sub_dual(callback=1) TSRFLP.sub_dual.optimize() # TSRFLP.update_multiple_scenario() TSRFLP.worst_scenario() TSRFLP.update_cut() model.cbLazy(TSRFLP.omega >= TSRFLP.constr_y) if where == GRB.Callback.MESSAGE: # Message callback msg = model.cbGet(GRB.Callback.MSG_STRING) cutname = 'Lazy constraints' if cutname in msg: TSRFLP.num_cut += int(msg[-2]) if time.time() - start_time >= 2000: model.terminate() TSRFLP = mr.rflp(p, ni, nk, a1, a2, cd, cdk, sk) TSRFLP.dual = 1 TSRFLP.intSP = 1 TSRFLP.lift = 0 TSRFLP.zero_half = 0 # -------------------- gap = 1 stop = 1e-5 # build = time.time() TSRFLP.master() # #print("BUILDING MASTER--- %s seconds ---" % round((time.time() - build), 2)) # build = time.time() TSRFLP.dual_sub(callback=1) # #print("BUILDING SUBDUAL--- %s seconds ---" % round((time.time() - build), 2)) # build = time.time() TSRFLP.sub(callback=1) # #print("BUILDING SUB--- %s seconds ---" % round((time.time() - build), 2)) TSRFLP.params_tuneup() # set initail time start_time = time.time() TSRFLP.master_model._lastnode = -GRB.INFINITY TSRFLP.master_model._vars = TSRFLP.master_model.getVars() TSRFLP.master_model.Params.lazyConstraints = 1 # TSRFLP.master_model.Params.TimeLimit = 2000 # 2000 seconds # warm start # TSRFLP.master_model.optimize() # TSRFLP.update_sub_dual(0) # TSRFLP.sub_dual.optimize() # TSRFLP.gap_calculation() # TSRFLP.master_model.addConstr(TSRFLP.a1*TSRFLP.master_model.getVars()[-1]+TSRFLP.a1*TSRFLP.omega >= TSRFLP.LB) TSRFLP.master_model.optimize(mycallback) # --------------- Integer L-shaped cut ----------------- # print(TSRFLP.master_model.MIPGap) # Check if reach optimal without integer cut TSRFLP.UB = GRB.INFINITY #reset TSRFLP.update_sub(callback=0) TSRFLP.sub_model.optimize() # TSRFLP.worst_scenario(1) TSRFLP.gap_calculation(0, 1) if abs(TSRFLP.gap) > 1e-4: # start integer cut print(TSRFLP.gap) # print('=========== Start Integer L-shaped cut =========') # TSRFLP.master_model.addConstr(TSRFLP.a1*TSRFLP.master_model.getVars()[-1]+TSRFLP.a1*TSRFLP.omega >= TSRFLP.master_model.Objval) TSRFLP.update_integer_cut() TSRFLP.master_model.addConstr(TSRFLP.omega >= TSRFLP.integer_cut) TSRFLP.master_model.optimize(mycallback_int) #print('Optimal solution found: %g' % TSRFLP.master_model.objVal) except GurobiError as e: print('Error code ' + str(e.errno) + ": " + str(e)) except AttributeError: print('Encountered an attribute error') # TSRFLP.error_check() #print("--- %s seconds ---" % round((time.time() - start_time), 2)) # OUTPUT runtime = round((time.time() - start_time), 2) if TSRFLP.master_model.Status == 2: TSRFLP.opt = 1 objval = round(TSRFLP.master_model.Objval, 2) gap = TSRFLP.master_model.MIPGap if abs(gap) <= 1e-5: gap = 0 var_y = [] for j in range(TSRFLP.ni): y_name = ''.join(['y[', str(j), ']']) y_temp = TSRFLP.master_model.getVarByName(y_name) var_y.append(y_temp.x) return var_y, runtime, TSRFLP.num_cut, TSRFLP.opt, objval, gap
def benders_deco(p,cd,cdk,sk,a1): # Number of nodes ni = len(cd) nk = len(cdk) # weights of two stages a2 = 1 - a1 start_time = time.time() TSRFLP = mr.rflp(p, ni, nk, a1, a2, cd, cdk, sk) #dual sub problem TSRFLP.dual = 1 # for dual sub problem TSRFLP.params_tuneup() TSRFLP.intSP = 1 #!!BINARY subproblem variable # ----------Benders' Decompisition---------- iteration = 0 stop = 1e-5 TSRFLP.master() while TSRFLP.gap >= stop or TSRFLP.int_gap >= stop: TSRFLP.master_model.optimize() TSRFLP.value_omega = TSRFLP.master_model.getVarByName('omega').x if TSRFLP.gap >= stop: # Benders' cut print('gap:',TSRFLP.gap) if iteration == 0: TSRFLP.dual_sub() TSRFLP.sub() TSRFLP.params_tuneup() else: TSRFLP.update_sub_dual() TSRFLP.sub_dual.optimize() TSRFLP.gap_calculation() TSRFLP.update_status() iteration += 1 TSRFLP.update_master() # add benders' cut else: # Integer cut print('int_gap:',TSRFLP.int_gap) TSRFLP.update_sub() TSRFLP.sub_model.optimize() TSRFLP.worst_scenario(1) # calculate max L3 TSRFLP.gap_calculation(1) if TSRFLP.int_gap >= 1e-4: TSRFLP.update_integer_cut() TSRFLP.master_model.addConstr(TSRFLP.omega >= TSRFLP.integer_cut) TSRFLP.update_status() iteration += 1 runtime = round((time.time() - start_time), 2) time_limit = 0 if runtime >= 2000: time_limit = 1 break # ------------Integer cut -------------- # if time_limit != 1: # # Check optimality with primal SP first # TSRFLP.UB = GRB.INFINITY #reset # TSRFLP.sub() # TSRFLP.sub_model.params.OutputFlag = 0 # # TSRFLP.update_sub(callback=0) # TSRFLP.sub_model.optimize() # # TSRFLP.worst_scenario(1) # TSRFLP.gap_calculation(0,1) # # print('========= Start Integer L-shaped cut ==========') # # while abs(TSRFLP.gap) > 1e-4 and time_limit != 1: # # Integer L-shaped cut # TSRFLP.update_integer_cut() # TSRFLP.master_model.addConstr(TSRFLP.omega >= TSRFLP.integer_cut) # # Benders' cut # TSRFLP.update_sub_dual() # TSRFLP.sub_dual.optimize() # TSRFLP.update_cut() # TSRFLP.master_model.addConstr(TSRFLP.omega >= TSRFLP.constr_y) # # time_master= time.time() # TSRFLP.master_model.optimize() # # print("---time_master--- %s seconds ---" % round((time.time() - time_sub), 2)) # TSRFLP.update_sub(callback=0) # # time_sub= time.time() # TSRFLP.sub_model.optimize() # # print("---time_sub--- %s seconds ---" % round((time.time() - time_sub), 2)) # # TSRFLP.worst_scenario(1) # worst sub obj (L3) # TSRFLP.gap_calculation(0,1) # calculate gap # # TSRFLP.update_status() # # iteration += 1 # runtime = round((time.time() - start_time), 2) # if runtime >= 2000: # break # print('Optimal Objective Value = ', str(TSRFLP.UB)) # print("--- %s seconds ---" % runtime) if TSRFLP.int_gap == float('inf'): gap = TSRFLP.gap print(gap) else: gap = TSRFLP.int_gap print(gap) if abs(gap) <= 1e-5: TSRFLP.opt = 1 gap = 0 objval = round(TSRFLP.UB,2) return runtime,iteration,TSRFLP.opt,objval,gap
def bra_cut(p, cd, cdk, sk, a1): # Number of nodes ni = len(cd) nk = len(cdk) # weights of two stages a2 = 1 - a1 try: def mycallback(model, where): # callback fuction: benders cut & integer cut # time1 = time.time() if where == GRB.Callback.MIPSOL: # status output # nodecnt = model.cbGet(GRB.Callback.MIPSOL_NODCNT) # obj = model.cbGet(GRB.Callback.MIPSOL_OBJ) # solcnt = model.cbGet(GRB.Callback.MIPSOL_SOLCNT) # objbst = model.cbGet(GRB.Callback.MIPSOL_OBJBST) # objbnd = model.cbGet(GRB.Callback.MIPSOL_OBJBND) # gap_mipsol = abs(objbst - objbnd)/(1.0 + abs(objbst)) # #print('**** New solution at node %d, obj %g, sol %d, ' # 'gap = %g ****' % (nodecnt, obj, solcnt, gap_mipsol)) vals = model.cbGetSolution(model._vars) TSRFLP.value_y = vals[-2 - ni:-2] # print(TSRFLP.value_y) if TSRFLP.warm == 'over': TSRFLP.value_y = [round(x) for x in TSRFLP.value_y ] # make sure y are binary TSRFLP.value_omega = vals[-1] TSRFLP.update_sub_dual(callback=1) # time_subdual = time.time() TSRFLP.sub_dual.optimize() max_Lk = TSRFLP.worst_scenario() # print("DUAL_SUB_callback--- %s seconds ---" % round((time.time() - time_subdual), 2)) if max_Lk[ 0] - TSRFLP.value_omega >= 1e-4: # ----benders cut---- TSRFLP.update_multiple_scenario() # print("callback--- %s seconds ---" % round((time.time() - time1), 2)) else: # ----integer cut---- time_sub = time.time() TSRFLP.update_sub(callback=1) TSRFLP.sub_model.optimize() print("PRIMAL_SUB_callback--- %s seconds ---" % round( (time.time() - time_sub), 2)) max1 = TSRFLP.worst_scenario(1) # calculate max L3 TSRFLP.gap_calculation(1) # calculate int_gap # print('----Integer gap:',TSRFLP.int_gap) # COVER time_cover = time.time() TSRFLP.cover_bound() # print("PRIMAL_BOUND_callback--- %s seconds ---" % round( (time.time() - time_cover), 2)) TSRFLP.sub_cover.optimize() print("PRIMAL_SUBCOVER_callback--- %s seconds ---" % round( (time.time() - time_cover), 2)) max2 = TSRFLP.worst_scenario(1, 1) # TSRFLP.gap_calculation(1, 0, 1) # print('max1 ',max1) # print('max2 ',max2) print(TSRFLP.sub_model.objVal) print(TSRFLP.sub_cover.objVal) # Debug ------------------------ # value_L3 = [] # value_L = [] # for k in range(TSRFLP.nk): # L3_name = ''.join(['L3[', str(k), ']']) # L_name = ''.join(['L[', str(k), ']']) # value_L3.append(TSRFLP.sub_model.getVarByName(L3_name).x) # value_L.append(TSRFLP.sub_cover.getVarByName(L_name).x) # print(value_L3) # print(value_L) # sys.stdout = open("sub.txt", "w") # print(TSRFLP.sub_model.getVars()) # sys.stdout = open("cover.txt", "w") # print(TSRFLP.sub_cover.getVars()) # sys.stdout = sys.__stdout__ # ---------------------- if TSRFLP.int_gap >= 1e-4: # cut incumbent solution TSRFLP.update_integer_cut( 1) #cover=0(sub_model)/1(sub_cover) model.cbLazy(TSRFLP.omega >= TSRFLP.integer_cut) # COVER if where == GRB.Callback.MESSAGE: # lazy constraints # Message callback msg = model.cbGet(GRB.Callback.MSG_STRING) cutname = 'Lazy constraints' if cutname in msg: TSRFLP.num_cut += int(msg[20:-1]) # print(time.time() - start_time) if time.time() - start_time >= 2000: model.terminate() TSRFLP = mr.rflp(p, ni, nk, a1, a2, cd, cdk, sk) # instantiate class # setting algorithm environment TSRFLP.dual = 1 TSRFLP.intSP = 1.0 TSRFLP.lift = 0 TSRFLP.zero_half = 0 # gap = 1 # # stop = 1e-5 # build = time.time() # TSRFLP.master() # needed when .warm_start is turned off # print("BUILDING MASTER--- %s seconds ---" % round((time.time() - build), 2)) # build = time.time() TSRFLP.dual_sub(callback=1) # # print("BUILDING SUBDUAL--- %s seconds ---" % round((time.time() - build), 2)) # build = time.time() TSRFLP.sub(callback=1) # # print("BUILDING SUB--- %s seconds ---" % round((time.time() - build), 2)) # COVER TSRFLP.cover_pre() TSRFLP.cover_sub() # sub_cover Model initialization # warm_t = time.time() TSRFLP.warm_start(1) # print("Warm time %s seconds" % round((time.time() - warm_t), 2)) TSRFLP.params_tuneup() # set initail time start_time = time.time() # TSRFLP.master_model._lastnode = -GRB.INFINITY TSRFLP.master_model._vars = TSRFLP.master_model.getVars() TSRFLP.master_model.Params.lazyConstraints = 1 # TSRFLP.master_model.optimize(mycallback) except GurobiError as e: print('Error code ' + str(e.errno) + ": " + str(e)) except AttributeError: print('Encountered an attribute error') # TSRFLP.error_check() # print("--- %s seconds ---" % round((time.time() - start_time), 2)) # OUTPUT runtime = round((time.time() - start_time), 2) if TSRFLP.master_model.Status == 2: TSRFLP.opt = 1 objval = round(TSRFLP.master_model.Objval, 2) gap = TSRFLP.master_model.MIPGap if abs(gap) <= 1e-5: gap = 0 var_y = [] for j in range(TSRFLP.ni): y_name = ''.join(['y[', str(j), ']']) y_temp = TSRFLP.master_model.getVarByName(y_name) var_y.append(y_temp.x) return var_y, runtime, TSRFLP.num_cut, TSRFLP.opt, objval, gap