Exemplo n.º 1
0
#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)
Exemplo n.º 2
0
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)
Exemplo n.º 3
0
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
Exemplo n.º 4
0
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
Exemplo n.º 6
0
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
Exemplo n.º 7
0
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
Exemplo n.º 8
0
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
Exemplo n.º 9
0
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
Exemplo n.º 10
0
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
Exemplo n.º 11
0
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
Exemplo n.º 12
0
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
Exemplo n.º 13
0
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