示例#1
0
# test class
import model_rflp as mr
#import data_generator1 as dg
#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:
示例#2
0
# -*- coding: utf-8 -*-
"""
Created on Wed Aug  1 08:24:56 2018
2-stage recoverable p-center model:
   Test if primal == dual
@author: DUBO
"""
#import data_generator1 as dg
import data_generator0 as dg0
data = dg0.data_gen(20, 20, 2)
p, cd, cdk, sk = data.data()
from gurobipy import *
ni = len(cd)
nk = len(cdk)
# weights of two stages
a1 = 0.5
a2 = 1 - a1


def cal_DualObj():
    # Q(k) = sum_i(sum_j(y_j*gamma_kij))+sumsum_ij((1-a_kj)*delta_kij
    #           + sum_i(epsilon_ki) + sum_j((1-y_j)*lambda_kj) +
    #           + sum_j((1-a_kj)*mu_kj) + (p+sum_j(a_kj*y_j)-sum(y_j))*nu_k
    sum_gamma = 0
    sum_delta = 0
    sum_epsilon = sum(epsilon)
    sum_lamda = 0
    sum_mu = 0
    sum_nu = (p + sum([sk[max_k][j] * value_y[j]
                       for j in range(ni)]) - sum(value_y)) * nu
    for i in range(ni):
示例#3
0
def pqcenter_compare(ni, p, rnd=None, survive=0):

    #---------------------- Problem setting -----------------------
    # p = round(ni / 2) # p
    if p == 1:
        sum_k = 1
    else:
        sum_k = int(round(p) * 0.5)  # sum_k
    data = dg0.data_gen(ni, 1, p, sum_k, rnd)  # ni,nk,randomseed
    _, cd, _, sk = data.data()
    if survive == 0:
        survive = round(p / 5) + 1  # survived facilities
    # Input value_y & sk
    value_y = [0 for j in range(ni)]
    # for j in range(math.ceil(p/2)):
    #     value_y[j] = 1
    y_0 = np.random.choice(range(ni), survive, replace=False)
    for x in y_0:
        value_y[x] = 1
    # sk[0] = [0 for j in range(ni)] #

    # a_ije
    # A = [[[0 for e in range(ne)] for j in range(ni)] for i in range(ni)]
    # for i in range(ni):
    #     for j in range(ni):
    #         for e in range(ne):
    #             if sk[j] == 0: # disrupted node so cannot cover??
    #                 if cd[i][j] <= cd1[e]:
    #                     A[i][j][e] = 1

    def p_center(cd, p=1, LP=0, value_y=0):
        m = Model("p-center")
        # Number of nodes
        ni = len(cd)
        # p = 1
        # Create variables
        # x:allocations y:location L:auxiliary variable
        x = m.addVars(ni, ni, vtype=GRB.CONTINUOUS, name="x")
        if LP == 0:
            y = m.addVars(ni, vtype=GRB.BINARY, name="y")
        elif LP == 1:
            y = m.addVars(ni, vtype=GRB.CONTINUOUS, name="y")
        L = m.addVar(vtype=GRB.CONTINUOUS, obj=1, name="L")
        # Set objective to minimize
        m.modelSense = GRB.MINIMIZE
        # (1) Maximum cost constraints (objective): L>sum(cdx) forall i
        cdx = x.copy()
        for i in range(ni):
            for j in range(ni):
                cdx[i, j] = cd[i][j]
        m.addConstrs((x.prod(cdx, i, '*') <= L for i in range(ni)), "epigraph")
        # (2) Constraints sum(y)=p
        m.addConstr((y.sum() == p), "p")
        # (3) x<=y forall i,j
        m.addConstrs((x[i, j] <= y[j] for i in range(ni) for j in range(ni)),
                     "x<y")
        # (4) sum(x)=1 forall i
        m.addConstrs((x.sum(i, '*') == 1 for i in range(ni)), "sumx")
        # save model and optimize
        # m.write('.\model\pcenter.lp')
        if LP == 0 and p != 1:
            m.params.OutputFlag = output
        else:
            m.params.OutputFlag = 0
        # m._vars = m.getVars()
        if value_y != 0:
            m.update()
            for j in range(ni):
                if value_y[j] == 1:
                    if sk[0][j] != 1:
                        y_name = ''.join(['y[', str(j), ']'])
                        m.getVarByName(y_name).lb = 1
                if sk[0][j] == 1:
                    y_name = ''.join(['y[', str(j), ']'])
                    m.getVarByName(y_name).ub = 0
        # m.params.NumericFocus = 2
        m.Params.TimeLimit = 1000
        m.optimize()
        # Output
        #    for v in m.getVars():
        #         # print('%s %g' % (v.varName, v.x))
        # # print('Obj: %g' % m.objVal)
        # # print('Runtime: %g' % m.Runtime)
        if LP == 0:
            Gap = m.MIPGap
        else:
            Gap = 0
        return m.objVal, m.Runtime, Gap

    def cover_p_center(a, cd1, ni, ne, p, value_y=0):
        # Create a new model
        m = Model("p-center-cover")

        # Create variables
        # z:ordered cost, y:location
        z = m.addVars(ne, vtype=GRB.BINARY, name="z")
        y = m.addVars(ni, vtype=GRB.BINARY, name="y")

        # Set objective to minimize
        m.modelSense = GRB.MINIMIZE
        # Minimize :\sum_e \rho_e*z_e
        m.setObjective(LinExpr(cd1, z.select()))
        # (1) \sum_j a_ije*y_j >= z_e \forall i,e
        for i in range(ni):
            for e in range(ne):
                sum_ay = 0
                for j in range(ni):
                    sum_ay += a[i][j][e] * y[j]
                m.addConstr((sum_ay >= z[e]), 'ay>e' + str(i) + str(e))
        # (2) \sum y_j = p
        m.addConstr((y.sum() == p), 'sump')
        # (3) \sum z_e = 1
        m.addConstr((z.sum() == 1), 'sumz')

        # m.addConstr(y[0] == 1)

        # save model and optimize
        # m.write('.\model\pcenter.lp')
        m.params.OutputFlag = output
        m.Params.TimeLimit = 1000
        # m.params.NumericFocus = 2
        # variable fixing
        if value_y != 0:
            m.update()
            for j in range(ni):
                if value_y[j] == 1:
                    if sk[0][j] != 1:
                        y_name = ''.join(['y[', str(j), ']'])
                        m.getVarByName(y_name).lb = 1
                if sk[0][j] == 1:
                    y_name = ''.join(['y[', str(j), ']'])
                    m.getVarByName(y_name).ub = 0
        # m._vars = m.getVars()
        m.optimize()

        # Output
        #    for v in m.getVars():
        #         # print('%s %g' % (v.varName, v.x))
        # print('Obj: %g' % m.objVal)
        # print('Runtime: %g' % m.Runtime)
        return m.objVal, m.Runtime, m.MIPGap

    # Preprocessing
    cd0 = list(itertools.chain.from_iterable(cd))  # combine lists
    cd1 = sorted(set(cd0))  # sort without duplicates
    ni = len(cd)

    t0 = time.time()
    # Find UB1
    y_initial = copy.deepcopy(value_y)
    # Construct sets
    y_set = set()
    for j in range(ni):
        if value_y[j] == 1:
            y_set.update({j})
    sk_set = set()
    for j in range(ni):
        if sk[0][j] == 1:
            sk_set.update({j})
    clear_list = list(range(ni))
    clear_set = set(clear_list)
    clear_set = clear_set.difference(y_set)
    clear_set = clear_set.difference(sk_set)
    # n = p # counter
    cd_matrix = np.array(cd)
    cd_matrix_1 = np.copy(cd_matrix)  # deep copy
    # **********************************************************
    # Find y heuristically
    # Plan 1 : (L no more than 2 times of optimality)
    # (a,b) = np.unravel_index(cd_matrix.argmax(), cd_matrix.shape) # index of maximum cost
    # y_set.update({a,b})
    # cd_matrix[a,b] = 0

    # UB1  Algorithm 1: find maximum cost to node in y_set
    # while len(y_set) < p:
    #     y_curr = list(y_set)
    #     cd_temp = cd_matrix[y_curr,:]
    #     (a,b) = np.unravel_index(cd_temp.argmax(), cd_temp.shape)
    #     cd_matrix[y_curr[a],b] = 0
    #     if sk[0][b] != 1:
    #         y_set.update({b})

    # UB1 Algorithm 2
    while len(y_set) < p:
        (a, b) = np.unravel_index(cd_matrix.argmax(),
                                  cd_matrix.shape)  # index of maximum cost
        if a in clear_set and b in clear_set:
            y_set.update({a, b})
        elif a in clear_set and b not in clear_set:
            y_set.update({a})
        elif a not in clear_set and b in clear_set:
            y_set.update({b})
        cd_matrix[a, b] = 0
    if len(y_set) > p:
        y_set.remove(b)
    #  Plan 2 (more than 2 times of optimality)?

    for x in y_set:
        y_initial[x] = 1

    # Construct x (|y| cluster) by finding closest facility
    x = [[0 for j in range(ni)] for i in range(ni)]
    for j in range(ni):
        if y_initial[j] == 0:
            cd_matrix_1[:, j] = 1e8  # set j column to Big M
    facility = np.argmin(cd_matrix_1,
                         axis=1)  # index of maximum value in each row
    cost = cd_matrix_1[
        np.arange(cd_matrix_1.shape[0]),
        facility]  # advanced index returning maximum value of each row
    UB1 = max(cost)  # Upper Bound UB1

    #b = np.min(cd_matrix_1, axis=1)
    for i in range(ni):
        x[i][facility[i]] = 1
    # print("Find UB1--- %s seconds ---" % round((time.time() - t0), 5))

    t1 = time.time()
    # Find UB2: Cluster
    cluster = [[] for n in range(p)]
    y_idx = list(y_set)
    for i in range(p):
        cluster[i] = np.argwhere(facility == y_idx[i]).ravel()  #.tolist()
    cd_array = np.array(cd)
    L_cluster = [0 for i in range(p)]
    for i in range(p):
        L_cluster[i], _, _ = p_center(cd_array[cluster[i][:, None],
                                               cluster[i]])
    UB2 = max(L_cluster)
    # print("Find UB2--- %s seconds ---" % round((time.time() - t1), 5))

    t2 = time.time()
    # LB2 = UB1/2  # Wrong Lower Bound
    LB2, _, _ = p_center(cd, p, 1)
    #    LB2=0
    # print("Find LB--- %s seconds ---" % round((time.time() - t2), 5))

    # **********************************************************
    # print(UB1)
    # print(UB2)
    # print(LB2)

    # using UB,LB to modify cd1
    cd1 = [x for x in cd1 if x >= LB2 and x <= UB2]
    ne = len(cd1)
    A = [[[0 for e in range(ne)] for j in range(ni)] for i in range(ni)]
    for i in range(ni):
        for j in range(ni):
            for e in range(ne):
                if cd[i][j] <= cd1[e]:
                    A[i][j][e] = 1
    obj0, T0, Gap0 = cover_p_center(A, cd1, ni, ne, p, value_y)  #
    obj1, T1, Gap1 = p_center(cd, p, 0, value_y)  #
    # print('Obj: %g' % obj1)
    # print('Runtime: %g' % T1)
    # print(y_set)
    return obj0, T0, Gap0, obj1, T1, Gap1
示例#4
0
ex_N = [20]  # number of vertexes
ex_k = [50, 20, 30, 40, 50]  # number of scenarios
ex_all = 10  # number of experiments for each combination
## bug
# 10,30,46
##
a1 = 0.5
rnd_seed = 6  # 17 # starting random seed
bug = []

try:
    result = []
    for n_N in ex_N:
        for n_k in ex_k:
            for n_e in range(ex_all):
                data = dg0.data_gen(n_N, n_k, rnd_seed)
                p, cd, cdk, sk = data.data()
                rnd_seed += 1
                while rnd_seed in bug:
                    rnd_seed += 1
                # print(rnd_seed)
                ###
                y1, t1, cut1, opt1, val1, gap1 = bc.bra_cut(p, cd, cdk, sk, a1)
                #                y1c,t1c, cut1c, opt1c, val1c, gap1c = bc_cover.bra_cut(p, cd, cdk, sk, a1)
                #                t2, cut2, opt2, val2, gap2 = bd.benders_deco(p, cd, cdk, sk, a1)
                y3, t3, opt3, val3, gap3 = lip.LIP(p, cd, cdk, sk, a1)
                ###
                # result_i = [n_N, n_k, rnd_seed, t1, cut1, opt1, val1, gap1,t2, cut2, opt2, val2, gap2, t3, opt3, val3, gap3]
                # result.append(result_i)
                # result_pd = pd.DataFrame(result, columns=('|N|', '|k|', 'seed', 'BC:time', 'cuts', 'opt', 'objval',
                #                            'gap', 'BD:time', 'cuts', 'opt', 'objval', 'gap', 'LIP:time', 'opt', 'objval', 'gap'))
示例#5
0
文件: LIP0.py 项目: dubo0111/Python
def one_stage(ni,sk,rnd,a1):
    data = dg0.data_gen(ni,sk,rnd)
    cd,cdk,sk,_ = data.illustrative()
    p=2

    start_time = time.time()

    try:

        # Create a new model
        m = Model("p-center")

        # Number of nodes
        ni = len(cd)
        # nk = len(cdk)
        nk = ni

        # Number of scenarios
        #nk = 1
        # weights of two stages
#        a1 = 0.4
        a2 = 1 - a1

        # --------- Master problem ---------
        # Create variables
        # x:allocations y:location L:auxiliary variable
        x = m.addVars(ni,ni,vtype=GRB.BINARY, name="x")
        y = m.addVars(ni,vtype=GRB.BINARY, name="y")
        L = m.addVar(vtype=GRB.CONTINUOUS,obj=a1,name="L")

        # Set objective to minimize
        m.modelSense = GRB.MINIMIZE
    #    m.params.OutputFlag = 0
        m.params.Presolve = 0
    #    m.params.ScaleFlag = 3
    #    m.params.NumericFocus = 3
        # (1) Maximum cost constraints (objective): L>sum(cdx) forall i
        cdx = x.copy()
        for i in range(ni):
            for j in range(ni):
               cdx[i,j]=cd[i][j]
        m.addConstrs(
                (x.prod(cdx,i,'*') <= L for i in range(ni)),
                "epigraph")
        # (2) Constraints sum(y)=p
        m.addConstr(
                (y.sum() == p),
                "p")
        # (3) x<=y forall i,j
        m.addConstrs(
                (x[i,j] <= y[j] for i in range(ni) for j in range(ni)),
                "x<y")
        # (4) sum(x)=1 forall i
        m.addConstrs(
                (x.sum(i,'*') == 1 for i in range(ni)),
                "sumx")
        m.params.OutputFlag = 0
        m.optimize()
    #    print('========================')
    #    print('L:',L.x)

        m1 = Model("p-center")
        # ---------- Sub problem ----------
        # v:allocations u:location L3,eta: auxiliary variable
        v = m1.addVars(nk,ni,ni,vtype=GRB.BINARY, name="v")
        u = m1.addVars(nk,ni,vtype=GRB.BINARY, name="u")
        L3 = m1.addVars(nk,vtype=GRB.CONTINUOUS, obj=0.00001,name="L3")
        eta = m1.addVar(vtype=GRB.CONTINUOUS, obj=a2, name="eta")

        #(5) eta >= L3(k) forall k
        m1.addConstrs(
                (eta >= L3[k] for k in range(nk)),
                "eta>k")
        #(6) L3(k) >= c'd'v(k) forall i,k
        cdv = v.copy()
        for k in range(nk):
            for i in range(ni):
                for j in range(ni):
                   cdv[k,i,j]=cdk[k][i][j]
        m1.addConstrs(
                (v.prod(cdv,k,i,'*') <= L3[k] for k in range(nk) for i in range(ni)),
                "sumcdv<L3k")
        #(7) v(k) <= y + u(k) forall k,i,j
        m1.addConstrs(
                (v[k,i,j] <= y[j].x + u[k,j] for k in range(nk) for i in range(ni) for j in range(ni)),
                "v<y+u")
        #(8) v(k) <= 1 - a_j(k) forall k,i,j
        m1.addConstrs(
                (v[k,i,j] <= 1 - sk[k][j] for k in range(nk) for i in range(ni) for j in range(ni)),
                "v<1-ak")
        #(9) sum(v) = 1 forall i,k
        m1.addConstrs(
                (v.sum(k,i,'*') == 1 for k in range(nk) for i in range(ni)),
                "sumv")
        #(10) u(k) + y <= 1 forall k,j
        m1.addConstrs(
                (u[k,j] + y[j].x <= 1 for k in range(nk) for j in range(ni)),
                "u+y<1")
        #(11) u(k) + a_j(k) <= 1 forall k,j
        m1.addConstrs(
                (u[k,j] + sk[k][j] <= 1 for k in range(nk) for j in range(ni)),
                "u+ak<1")
        #(12) sum(u(k)) + sum(y) - sum(a_j(k)*y) = p forall k (or <=)
        sumy = 0
        for j in range(ni):
            sumy += y[j].x
        for k in range(nk):
            sumky = 0
            for j in range(ni):
                sumky += y[j].x * sk[k][j]
            m1.addConstr(
                    (u.sum(k,'*') + sumy - sumky == p),
                    "2S-p")
        # save model and optimize
    #    m.write(".\model\LIP.lp")
        m1.params.OutputFlag = 0
        m1.optimize()

        #Output
    #    for v in m.getVars():
    #         print('%s %g' % (v.varName, v.x))
        value_L = m.getVarByName('L')
        value_eta = m1.getVarByName('eta')
    #    print('Obj: %g' % m.objVal)

    except GurobiError as e:
        print('Error code ' + str(e.errno) + ": " + str(e))
    except AttributeError:
        print('Encountered an attribute error')
    print('=================LIP SOLUTION==================')
    print('1st stage:',L.x)
    print('2nd stage:',eta.x)
    print('obj:',a1*L.x+a2*eta.x)

    # print("--- %s seconds ---" % round((time.time() - start_time),2))

    value_y = []
    for j in range(ni):
        y_name = ''.join(['y[',str(j),']'])
        value_y.append(m.getVarByName(y_name).x)
    value_x = [[0 for j in range(ni)] for i in range(ni)]
    for i in range(ni):
        for j in range(ni):
            x_name = ''.join(['x[',str(i),',',str(j),']'])
            value_x[i][j] = m.getVarByName(x_name).x
    value_u =  [[0 for j in range(ni)] for k in range(nk)]
    for k in range(nk):
        for i in range(ni):
            u_name = ''.join(['u[',str(k),',',str(i),']'])
            value_u[k][i] = m1.getVarByName(u_name).x
    value_v =[[[0 for j in range(ni)] for i in range(ni)] for k in range(nk)]
    for k in range(nk):
        for i in range(ni):
            for j in range(ni):
                v_name = ''.join(['v[',str(k),',',str(i),',',str(j),']'])
                value_v[k][i][j]= m1.getVarByName(v_name).x
    value_L3 = []
    for k in range(nk):
        L3_name = ''.join(['L3[',str(k),']'])
        value_L3.append(m1.getVarByName(L3_name).x)

    return L.x, eta.x,cd,value_y,value_x,value_u,value_v,value_L3
示例#6
0
# -*- coding: utf-8 -*-
"""
Created on Tue Oct 28 2018

@author: DUBO

p-center model (cover formulation)
"""
import data_generator0 as dg0
data = dg0.data_gen(50,1) # ni,nk,randomseed
p,cd,_,_ = data.data()
from gurobipy import *
import numpy as np
import itertools
import sys
import time


def p_center(cd,p=1,LP=0):
    m = Model("p-center")
    # Number of nodes
    ni = len(cd)
    # p = 1
    # Create variables
    # x:allocations y:location L:auxiliary variable
    x = m.addVars(ni,ni,vtype=GRB.CONTINUOUS, name="x")
    if LP == 0:
        y = m.addVars(ni,vtype=GRB.BINARY, name="y")
    elif LP == 1:
        y = m.addVars(ni,vtype=GRB.CONTINUOUS, name="y")
    L = m.addVar(vtype=GRB.CONTINUOUS,obj=1,name="L")
示例#7
0
# Branch and cut + Integer L-shaped cut

import model_rflp as mr
import data_generator0 as dg0
from gurobipy import *
import time

data = dg0.data_gen(30, 100, 21)
p, cd, cdk, sk = data.data()

# Number of nodes
ni = len(cd)
nk = len(cdk)
# weights of two stages
a1 = 0.5
a2 = 1 - a1
try:
    # if gap doesn't change for * iterations, add fractional cut
    gap_cnt = [-GRB.INFINITY, GRB.INFINITY]
    gap_iter = 0

    def mycallback(model, where):
        # if where == GRB.Callback.MIPNODE:
        #     nodecnt = model.cbGet(GRB.Callback.MIPNODE_NODCNT)
        if where == GRB.Callback.MIPSOL:
            vals = model.cbGetSolution(model._vars)
            TSRFLP.value_y = vals[-2 - ni:-2]
            TSRFLP.value_omega = vals[-1]
            TSRFLP.update_sub_dual(callback=1)
            TSRFLP.sub_dual.optimize()
            TSRFLP.worst_scenario()
示例#8
0
# -*- coding: utf-8 -*-
"""
Created on Tue Jul 25 2018

@author: DUBO

p-center model
"""
#import data_generator1 as dg
#INPUT Parameters:p, cost matrix
#p,cd = dg.ins_small()
#p,cd = dg.ins_big(100)
import data_generator0 as dg0
data = dg0.data_gen(50, 1, 3)
p, cd, cdk, sk = data.data()

from gurobipy import *
# def mycallback(model, where):
#     if where == GRB.Callback.MIPSOL:
#         print('-----------------------')
#         print(model.cbGetSolution(model._vars))

try:

    # Create a new model
    m = Model("p-center")

    # Number of nodes
    ni = len(cd)

    # Create variables
示例#9
0
# -*- coding: utf-8 -*-
"""
Created on Tue Jul 26 2018

2-stage recoverable p-center model:
    Linear Reformulation

@author: DUBO
"""
#%reset -f
import time
#import data_generator1 as dg
import data_generator0 as dg0
#INPUT Parameters:p, cost matrix
data = dg0.data_gen(10,20,2)
p,cd,cdk,sk = data.data()

from gurobipy import *
start_time = time.time()

try:

    # Create a new model
    m = Model("p-center")

    # Number of nodes
    ni = len(cd)
    nk = len(cdk)

    # Number of scenarios
    #nk = 1
示例#10
0
# Branch and cut
# ROOT NODE RELAXATION
import model_rflp as mr
#import data_generator1 as dg
#p, cd, cdk, sk = dg.ins_k(20, 100, 40)  # (ni,nk,randomseed*)
import data_generator0 as dg0
import numpy as np

rn = np.random.randint(10000)
rn
data = dg0.data_gen(30, 200, 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.4
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.MIPNODE:
            nodecnt = model.cbGet(GRB.Callback.MIPNODE_NODCNT)
            # if model.cbGet(GRB.Callback.MIPNODE_STATUS) == GRB.Status.OPTIMAL:
            #         vals = model.cbGetNodeRel(model._vars)
            #         TSRFLP.value_y = vals[-2 - ni:-2]
            #         TSRFLP.update_sub_dual(callback=1)
            #         TSRFLP.sub_dual.optimize()
示例#11
0
# Branch and cut
# multiple scenario generation
import model_rflp as mr
#import data_generator1 as dg
#p, cd, cdk, sk = dg.ins_k(20, 100, 40)  # (ni,nk,randomseed*)
import data_generator0 as dg0

data = dg0.data_gen(30, 20, 2)
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.4
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.MIPNODE:
            nodecnt = model.cbGet(GRB.Callback.MIPNODE_NODCNT)
            # if model.cbGet(GRB.Callback.MIPNODE_STATUS) == GRB.Status.OPTIMAL:
            #         vals = model.cbGetNodeRel(model._vars)
            #         TSRFLP.value_y = vals[-2 - ni:-2]
            #         TSRFLP.update_sub_dual(callback=1)
            #         TSRFLP.sub_dual.optimize()
            #         TSRFLP.update_multiple_scenario()
            #         TSRFLP.worst_scenario()
            #         TSRFLP.update_cut()