# 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:
# -*- 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):
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
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'))
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
# -*- 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")
# 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()
# -*- 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
# -*- 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
# 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()
# 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()