def SolveDetModel(self, demandScenario): def GetResults(self, DetModel, I, Z, Transshipment_X): resultsdict = {} plants = range(self.supplier) items = range(self.holding_cost.shape[0]) resultsdict['# of Open DC'] = sum([Z[i].x for i in plants]) resultsdict['Open DC'] = [Z[i].x for i in plants] resultsdict['Total Inventory'] = sum( [I[k, i].x for k in items for i in plants]) resultsdict['Inventory'] = [[I[k, i].x for i in plants] for k in items] resultsdict['Fixed Cost'] = sum( [Z[i].x * self.fixed_cost[i] for i in plants]) resultsdict['Holding Cost'] = [ sum([I[k, i].x * self.holding_cost[k, i] for i in plants]) for k in items ] return resultsdict DetModel = grb.Model('DetModel') DetModel.setParam('OutputFlag', 0) DetModel.modelSense = grb.GRB.MINIMIZE plants = range(self.supplier) demand = range(self.retailer) items = range(self.lower_demand.shape[0]) I = DetModel.addVars(items, plants, vtype=grb.GRB.CONTINUOUS, name='I') Z = DetModel.addVars(plants, vtype=grb.GRB.BINARY, name='Z') Transshipment_X = DetModel.addVars(items, plants, demand, vtype=grb.GRB.CONTINUOUS, name='Transshipment_X') objFunc_holding = sum( [I[k, i] * self.holding_cost[k, i] for k in items for i in plants]) objFunc_fixed = sum([Z[i] * self.fixed_cost[i] for i in plants]) objFunc_transportation = grb.quicksum([ Transshipment_X[k, i, j] * self.transportation_cost[k, i, j] for k in items for i in plants for j in demand ]) objFunc = objFunc_holding + objFunc_fixed + objFunc_transportation DetModel.setObjective(objFunc) #添加评估模型的约束 #约束1 for i in plants: for k in items: DetModel.addConstr( grb.quicksum([Transshipment_X[k, i, j] for j in demand]) <= I[k, i]) #约束2 for j in demand: for k in items: DetModel.addConstr( grb.quicksum([Transshipment_X[k, i, j] for i in plants]) == demandScenario[k, j]) #约束3 其实是paper中的4,gurobi自带正数约束 for i in plants: for j in demand: if round(self.graph[i, j]) == 0: for k in items: DetModel.addConstr(Transshipment_X[k, i, j] <= 0) #约束4 I_i<=M*Z_i for i in plants: for k in items: DetModel.addConstr(I[k, i] <= 100000 * Z[i]) #求解评估模型 DetModel.optimize() return GetResults(self, DetModel, I, Z, Transshipment_X)
def learn_rule(self, domain, data, pos_uncovered_indices, neg_indices): # Create a new model m = milp.Model("kDNF") print("Data") for row, l in data: print(*([ "{}: {:.2f}".format(v, Learner._convert(row[v])) for v in domain.variables ] + [l])) print() # --- Computed constants n_r = len(domain.real_vars) n_b = len(domain.bool_vars) n_h = self.max_hyperplanes_per_rule n_e = len(data) k = self.max_terms_per_rule mu = 0.005 x_er = [[Learner._convert(row[v]) for v in domain.real_vars] for row, _ in data] x_eb = [[Learner._convert(row[v]) for v in domain.bool_vars] for row, _ in data] # --- Variables # Inequality h is selected for the rule s_h = [ m.addVar(vtype=milp.GRB.BINARY, name="s_h({h})".format(h=h)) for h in range(n_h) ] # Example e covered by inequality h c_eh = [[ m.addVar(vtype=milp.GRB.BINARY, name="c_eh({e}, {h})".format(e=e, h=h)) for h in range(n_h) ] for e in range(n_e)] # Example e covered by rule c_e = [ m.addVar(vtype=milp.GRB.BINARY, name="c_e({e})".format(e=e)) for e in range(n_e) ] # Boolean feature (or negation) selected s_b = [ m.addVar(vtype=milp.GRB.BINARY, name="s_b({b})".format(b=b)) for b in range(2 * n_b) ] # Coefficient of the r-th variable of inequality h a_hr = [[ m.addVar(vtype=milp.GRB.CONTINUOUS, lb=-1, ub=1, name="a_hr({h}, {r})".format(h=h, r=r)) for r in range(n_r) ] for h in range(n_h)] # Offset of inequality h b_h = [ m.addVar(vtype=milp.GRB.CONTINUOUS, lb=-1, ub=1, name="b_h({h})".format(h=h)) for h in range(n_h) ] b_abs_h = [ m.addVar(vtype=milp.GRB.CONTINUOUS, lb=-1, ub=1, name="b_abs_h({h})".format(h=h)) for h in range(n_h) ] # Auxiliary variable (c_eh AND s_h) and_eh = [[ m.addVar(vtype=milp.GRB.BINARY, name="and_eh({e}, {h})".format(e=e, h=h)) for h in range(n_h) ] for e in range(n_e)] # Auxiliary variable (x_eb AND s_b) and_eb = [[ m.addVar(vtype=milp.GRB.BINARY, name="and_eb({e}, {b})".format(e=e, b=b)) for b in range(n_b) ] for e in range(n_e)] print() # Set objective m.setObjective(sum(c_e[e] for e in range(n_e) if data[e][1]), milp.GRB.MAXIMIZE) # Add constraint: and_eh <= c_eh for e in range(n_e): if not data[e][1]: for h in range(n_h): name = "and_eh({e}, {h}) <= c_eh({e}, {h})".format(e=e, h=h) m.addConstr(and_eh[e][h] <= c_eh[e][h], name) print(name) print() # Add constraint: and_eh <= s_h for e in range(n_e): if not data[e][1]: for h in range(n_h): name = "and_eh({e}, {h}) <= s_h({h})".format(e=e, h=h) m.addConstr(and_eh[e][h] <= s_h[h], name) print(name) print() # Add constraint: and_eh >= c_eh + s_h - 1 for e in range(n_e): if not data[e][1]: for h in range(n_h): name = "and_eh({e}, {h}) >= c_eh({e}, {h}) + s_h({h}) - 1".format( e=e, h=h) m.addConstr(and_eh[e][h] >= c_eh[e][h] + s_h[h] - 1, name) print(name) print() # Add constraint: and_eb <= x_eb for e in range(n_e): if not data[e][1]: for b in range(2 * n_b): name = "and_eb({e}, {b}) <= x_eb({e}, {b})".format(e=e, b=b) m.addConstr( and_eb[e][b] <= (x_eb[e][b] if b < n_b else 1 - x_eb[e][b]), name) print(name) print() # Add constraint: and_eb <= s_h for e in range(n_e): if not data[e][1]: for b in range(2 * n_b): name = "and_eb({e}, {b}) <= s_b({b})".format(e=e, b=b) m.addConstr(and_eb[e][b] <= s_b[b], name) print(name) print() # Add constraint: and_eb >= x_eb + s_b - 1 for e in range(n_e): if not data[e][1]: for b in range(2 * n_b): name = "and_eb({e}, {b}) >= x_eb({e}, {b}) + s_b({b}) - 1".format( e=e, b=b) m.addConstr( and_eb[e][b] >= (x_eb[e][b] if b < n_b else 1 - x_eb[e][b]) + s_b[b] - 1, name) print(name) print() # Add constraint: SUM_(h = 1..n_h) and_eh - s_h + SUM_(b = 1..2 * n_b) and_eb - s_b <= -1 for e in range(n_e): if not data[e][1]: name = "SUM_(h = 1..n_h) and_eh({e}, h) - s_h(h) + SUM_(b = 1..2*n_b) and_eb({e}, b) - s_b(b) <= -1"\ .format(e=e) m.addConstr( sum(and_eh[e][h] - s_h[h] for h in range(n_h)) + sum(and_eb[e][b] - s_b[b] for b in range(2 * n_b)) <= -1, name) print(name) # Add constraint: c_e <= c_eh + (1 - s_h) for e in range(n_e): if data[e][1]: for h in range(n_h): name = "c_e({e}) <= c_eh({e}, {h}) + (1 - s_h({h}))".format( e=e, h=h) m.addConstr(c_e[e] <= c_eh[e][h] + (1 - s_h[h]), name) print(name) # Add constraint: c_e <= x_eb + (1 - s_b) for e in range(n_e): if data[e][1]: for b in range(2 * n_b): name = "c_e({e}) <= x_eb({e}, {b}) + (1 - s_b({b}))".format( e=e, b=b) m.addConstr(c_e[e] <= x_eb[e][b] + (1 - s_b[b]), name) print(name) # Add constraint: SUM_(r = 1..n_r) a_hr * x_er <= b_h + 2 * (1 - c_eh) for e in range(n_e): for h in range(n_h): name = "SUM_(r = 1..n_r) a_hr({h}, r) * x_er({e}, r) <= b_h({h}) + 2 * (1 - c_eh({e}, {h}))"\ .format(e=e, h=h) m.addConstr( sum(a_hr[h][r] * x_er[e][r] for r in range(n_r)) <= b_h[h] + 2 * (1 - c_eh[e][h]), name) print(name) # Add constraint: SUM_(r = 1..n_r) a_hr * x_er >= b_h - mu - 2 * c_eh for e in range(n_e): for h in range(n_h): name = "SUM_(r = 1..n_r) a_hr({h}, r) * x_er({e}, r) >= b_h({h}) - mu - 2 * c_eh({e}, {h})"\ .format(e=e, h=h) m.addConstr( sum(a_hr[h][r] * x_er[e][r] for r in range(n_r)) >= b_h[h] + mu - 2 * c_eh[e][h], name) print(name) # Add constraint: SUM_(h = 1..n_h) s_h + SUM_(b = 1..n_b) s_b <= k name = "SUM_(h = 1..n_h) s_h(h) + SUM_(b = 1..n_b) s_b(b) <= k" m.addConstr( sum(s_h[h] for h in range(n_h)) + sum(s_b[b] for b in range(2 * n_b)) <= k, name) print(name) # Hack example # m.addConstr(a[0][0] == 1) # m.addConstr(a[0][1] == 0) # m.addConstr(b[0] == 0.5) # # m.addConstr(a[1][0] == 0) # m.addConstr(a[1][1] == 1) # m.addConstr(b[1] == 0.5) # # m.addConstr(a[2][0] == -1) # m.addConstr(a[2][1] == 0) # m.addConstr(b[2] == -0.5) # # m.addConstr(a[3][0] == 0) # m.addConstr(a[3][1] == -1) # m.addConstr(b[3] == -0.5) # # m.addConstr(s_h[0] == 1) # m.addConstr(s_h[1] == 1) # m.addConstr(s_h[2] == 1) # m.addConstr(s_h[3] == 1) # m.addConstr(z_h[0][0] == 1) # m.addConstr(z_h[1][0] == 1) # m.addConstr(z_h[2][0] == 0) # m.addConstr(z_h[3][0] == 0) # m.addConstr(z_h[0][1] == 0) # m.addConstr(z_h[1][1] == 0) # m.addConstr(z_h[2][1] == 1) # m.addConstr(z_h[3][1] == 1) # m.addConstr(z_ih[0][0] == 1) # m.addConstr(z_ih[1][0] == 0) # m.addConstr(z_ih[2][0] == 1) # m.addConstr(z_ih[3][0] == 0) # m.addConstr(z_ih[0][1] == 1) # m.addConstr(z_ih[1][1] == 0) # m.addConstr(z_ih[2][1] == 0) # m.addConstr(z_ih[3][1] == 1) # m.addConstr(z_ih[0][2] == 0) # m.addConstr(z_ih[1][2] == 1) # m.addConstr(z_ih[2][2] == 0) # m.addConstr(z_ih[3][2] == 1) # m.addConstr(z_ih[0][3] == 0) # m.addConstr(z_ih[1][3] == 1) # m.addConstr(z_ih[2][3] == 1) # m.addConstr(z_ih[3][3] == 0) # m.addConstr(z_d[0][0] == 1) # m.addConstr(z_d[1][0] == 0) # m.addConstr(z_d[2][0] == 0) # m.addConstr(z_d[3][0] == 0) # m.addConstr(z_d[0][1] == 0) # m.addConstr(z_d[1][1] == 0) # m.addConstr(z_d[2][1] == 1) # m.addConstr(z_d[3][1] == 0) # Wrong solution # m.addConstr(a[0][0] == 1) # m.addConstr(a[0][1] == 0) # m.addConstr(b[0] == 0.5) # # m.addConstr(a[1][0] == 0) # m.addConstr(a[1][1] == 1) # m.addConstr(b[1] == 0.5) # # m.addConstr(a[2][0] == -1) # m.addConstr(a[2][1] == 0) # m.addConstr(b[2] == -0.6) # # m.addConstr(a[3][0] == 0) # m.addConstr(a[3][1] == -1) # m.addConstr(b[3] == -0.6) # # m.addConstr(s_h[0] == 1) # m.addConstr(s_h[1] == 1) # m.addConstr(s_h[2] == 1) # m.addConstr(s_h[3] == 1) # m.addConstr(s_h[0] == 1) # m.addConstr(s_h[1] == 1) # m.addConstr(s_h[2] == 0) # m.addConstr(s_h[3] == 0) # # m.addConstr(a_hr[0][0] == -1) # m.addConstr(a_hr[0][1] == -0.5) # m.addConstr(b_h[0] == -0.2) # # m.addConstr(a_hr[1][0] == 1) # m.addConstr(a_hr[1][1] == 0) # m.addConstr(b_h[1] == 0.75) m.optimize() for v in m.getVars(): print(v.varName, v.x) print('Obj:', m.objVal) print() # Lets extract the rule formulation rule = [] from pysmt.shortcuts import Real, LE, Plus, Times, Not for h in range(n_h): if int(s_h[h].x) == 1: coefficients = [Real(float(a_hr[h][r].x)) for r in range(n_r)] constant = Real(float(b_h[h].x)) linear_sum = Plus([ Times(c, domain.get_symbol(v)) for c, v in zip(coefficients, domain.real_vars) ]) rule.append(LE(linear_sum, constant)) for b in range(2 * n_b): if int(s_b[b].x) == 1: var = domain.get_symbol(domain.bool_vars[b if b < n_b else b - n_b]) rule.append(var if b < n_b else Not(var)) print("Features", x_er[4][0], x_er[4][1]) print(sum(a_hr[1][r].x * x_er[4][r] for r in range(n_r)), "<=", b_h[1].x + 2 * (1 - c_eh[4][1].x)) print(sum(a_hr[1][r].x * x_er[4][r] for r in range(n_r)), ">=", b_h[1].x + mu - 2 * c_eh[4][1].x) return rule
def SolveStoModel(self, STOMODELCONFIGURE): def GetResults(self, I, Z, Transshipment_X, N): plants = range(self.supplier) items = range(self.lower_demand.shape[0]) objVal_holding = sum([ I[k, i].x * self.holding_cost[k, i] for k in items for i in plants ]) objVal_fixed = sum([Z[i].x * self.fixed_cost[i] for i in plants]) resultsdict = {} plants = range(self.supplier) resultsdict['# of Open DC'] = sum([Z[i].x for i in plants]) resultsdict['Open DC'] = [Z[i].x for i in plants] resultsdict['Total Inventory'] = [ sum([I[k, i].x for i in plants]) for k in items ] resultsdict['Inventory'] = [[I[k, i].x for i in plants] for k in items] resultsdict['Fixed Cost'] = objVal_fixed resultsdict['Holding Cost'] = [ sum([I[k, i].x * self.holding_cost[k, i] for i in plants]) for k in items ] return resultsdict N = STOMODELCONFIGURE['#'] demandScenario = STOMODELCONFIGURE['demandScenario'] StoModel = grb.Model('StoModel') StoModel.setParam('OutputFlag', 0) StoModel.modelSense = grb.GRB.MINIMIZE items = range(demandScenario.shape[0]) plants = range(self.supplier) demand = range(self.retailer) I = StoModel.addVars(items, plants, vtype=grb.GRB.CONTINUOUS, name='I') Z = StoModel.addVars(plants, vtype=grb.GRB.BINARY, name='Z') Transshipment_X = StoModel.addVars(items, range(N), plants, demand, vtype=grb.GRB.CONTINUOUS, name='Transshipment_X') objFunc_holding = grb.quicksum( [I[k, i] * self.holding_cost[k, i] for k in items for i in plants]) objFunc_fixed = grb.quicksum( [Z[i] * self.fixed_cost[i] for i in plants]) objFunc_penalty = grb.quicksum([ grb.quicksum([ self.penalty_cost[k, j] * (demandScenario[k, scenario, j] - grb.quicksum( [Transshipment_X[k, scenario, i, j] for i in plants])) for k in items for j in demand ]) for scenario in range(N) ]) objFunc_trans = grb.quicksum([ Transshipment_X[k, scenario, i, j] * self.transportation_cost[k, i, j] for scenario in range(N) for k in items for i in plants for j in demand ]) #N个Scenario的transportation cost总和 objFunc = objFunc_holding + objFunc_fixed + (objFunc_penalty + objFunc_trans) / N StoModel.setObjective(objFunc) ''' TODO ''' #约束1 for i in plants: for k in items: StoModel.addConstrs((grb.quicksum( [Transshipment_X[k, scenario, i, j] for j in demand]) <= I[k, i] for scenario in range(N))) #约束2 for j in demand: for k in items: StoModel.addConstrs((grb.quicksum( [Transshipment_X[k, scenario, i, j] for i in plants]) <= demandScenario[k, scenario, j] for scenario in range(N))) #约束3 for i in plants: for j in demand: for k in items: if round(self.graph[i, j]) == 0: StoModel.addConstrs( (Transshipment_X[k, scenario, i, j] <= 0 for scenario in range(N))) #约束4 I_i<=M*Z_i for i in plants: for k in items: StoModel.addConstr(I[k, i] <= 100000 * Z[i]) #求解评估模型 StoModel.optimize() return GetResults(self, I, Z, Transshipment_X, N)
b = np.asarray([[ 0, 0, -SCENARIOS[n][0], SCENARIOS[n][0] * 0.8, -SCENARIOS[n][1], SCENARIOS[n][1] * 0.8 ] for n in range(k)]) ''' Step 1: 1.0. establish the master problem 1.1. add initial constraints 1.2. solve master problem 1.3. get solutions(x,\ita) for the subproblem ''' # --- 1.0. establish master Model with scenarios #Build Model masterProblem = grb.Model('MasterProblem') masterProblem.modelSense = grb.GRB.MINIMIZE masterProblem.setParam('OutputFlag', 0) #Create Variables #First-stage Variables X = masterProblem.addVars([1, 2], vtype=grb.GRB.CONTINUOUS, lb=[0, 0], obj=[3, 2], name='X') #Second-stage recourse value variables ITA = masterProblem.addVars( range(1, k + 1), vtype=grb.GRB.CONTINUOUS,
def Calculate_Upper_bound(self,customer_sequence): #TODO check compatibility and correctness #Input: List customer_sequence: 每个元素是客户类对象 #Output: #通过解Paat Lemma1 中的LP得到Upper Bound from gurobipy import gurobipy as grb customer_sequence = [customer.type for customer in customer_sequence] #--- 申明问题 primal_problem = grb.Model() primal_problem.setParam('OutputFlag',0) primal_problem.modelSense = grb.GRB.MAXIMIZE #--- 申明变量 num_col = len(customer_sequence) num_row = int(len(self.possible_offer_set)/len(self.customer)) Y = primal_problem.addVars(range(num_row),range(1,num_col+1), #行:set集合,index从0开始; 列:时间T,index从1开始 vtype=grb.GRB.CONTINUOUS, lb=0,ub=1, name='y') #--- 设置objective function obj = 0 for t,customer_type in enumerate(customer_sequence): t = t+1 #时间变到正常的从1 开始 到 T for s,offer_set in enumerate(self.possible_offer_set[:num_row]): key = json.dumps({ 'customer_type':customer_type, 'offered_set':offer_set }) item_prob = self.PROBABILITY[key] for item_id in offer_set: # 不在offer_set里面无收益 obj += item_prob[item_id]*self.item[item_id]['price']*Y[s,t] primal_problem.setObjective(obj) #--- 加入constraints #capacity 限制 for item_id in list(self.item.keys())[1:]: possible_buy_number = 0 for t,customer_type in enumerate(customer_sequence): t = t+1 #时间变到正常的从1 开始 到 T for s,offer_set in enumerate(self.possible_offer_set[:num_row]): if item_id in offer_set: key = json.dumps({ 'customer_type':customer_type, 'offered_set':offer_set }) item_prob = self.PROBABILITY[key] possible_buy_number += item_prob[item_id]*Y[s,t] primal_problem.addConstr(possible_buy_number<=self.item[item_id]['initial_inventory']+self.item[item_id]['extra_inventory']) #possibility 约束 for t in range(1,len(customer_sequence)+1): #1-->T possibility = grb.quicksum([Y[s,t] for s in range(len(self.possible_offer_set[:num_row]))]) primal_problem.addConstr(possibility==1) primal_problem.write('11.lp') primal_problem.optimize() if primal_problem.status == grb.GRB.Status.OPTIMAL: print('successfully get hindsight upper bound') return primal_problem.ObjVal elif primal_problem.status == grb.GRB.Status.INFEASIBLE: print('upper bound model is infeasible.') else: print('something wrong with solving upper bound problem.')
def simulationWithCost_Multi(a, demand, Z, I, num_plants, num_demand, tranposrtation_cost, penalty_cost, cishu=500): print('--------Mixed_distribution_simulation----------') #lower_demand = demand[0] #mean_demand = demand[1] #upper_demand = demand[2] realized_demand = np.zeros(shape=(cishu, num_demand)) realized_demand = demand items = range(realized_demand.shape[0]) plants = range(num_plants) demand = range(num_demand) results = [] trans_cost_array = np.zeros(shape=(cishu, realized_demand.shape[0])) penal_cost_array = np.zeros(shape=(cishu, realized_demand.shape[0])) for n in range(cishu): oneDemandScenario = realized_demand[:, n, :] #申明Fillrate中Z(w)值的那个模型 evaluation_problem = grb.Model('evaluation_problem') evaluation_problem.setParam('OutputFlag', 0) evaluation_problem.modelSense = grb.GRB.MINIMIZE evaluation_X = evaluation_problem.addVars(items, plants, demand, vtype=grb.GRB.CONTINUOUS, name='evaluation_X') objFunc_penal = grb.quicksum([ penalty_cost[k, j] * (oneDemandScenario[k, j] - grb.quicksum([evaluation_X[k, i, j] for i in plants])) for k in items for j in demand ]) objFunc_trans = grb.quicksum( evaluation_X[k, i, j] * tranposrtation_cost[k, i, j] for k in items for i in plants for j in demand) evaluation_problem.setObjective(objFunc_penal + objFunc_trans) #添加评估模型的约束 #约束1 for k in items: for i in plants: evaluation_problem.addConstr( grb.quicksum([evaluation_X[k, i, j] for j in demand]) <= I[k, i]) #约束2 for k in items: for j in demand: evaluation_problem.addConstr( grb.quicksum([evaluation_X[k, i, j] for i in plants]) <= oneDemandScenario[k, j]) #约束3 其实是paper中的4,gurobi自带正数约束 for i in plants: for j in demand: if round(a[i, j] * Z[i]) == 0: for k in items: evaluation_problem.addConstr( evaluation_X[k, i, j] <= 0) #求解评估模型,并求出fillrate 还要输出 evaluation_problem.optimize() #transportation trans = np.zeros(shape=(realized_demand.shape[0], num_plants, num_demand)) for k in items: for i in plants: for j in demand: trans[k, i, j] = evaluation_X[k, i, j].x type1ServiceLevel = (np.abs(trans.sum(axis=1) - oneDemandScenario) <= 0.0005).sum() / (num_demand * realized_demand.shape[0]) type2ServiceLevel = trans.sum() / oneDemandScenario.sum() trans_cost = (trans * tranposrtation_cost).sum(axis=1).sum(axis=1) penal_cost = ((oneDemandScenario - trans.sum(axis=1)) * penalty_cost).sum(axis=1) results.append([ type1ServiceLevel, type2ServiceLevel, trans_cost.sum(), penal_cost.sum() ]) trans_cost_array[n, :] = trans_cost penal_cost_array[n, :] = penal_cost type1ServiceLevel_mean, type2ServiceLevel_mean, trans_cost_mean, penal_cost_mean = np.mean( np.asarray(results), axis=0) trans_cost_mean = [cost for cost in np.mean(trans_cost_array, axis=0)] penal_cost_mean = [cost for cost in np.mean(penal_cost_array, axis=0)] type1ServiceLevel_worst, type2ServiceLevel_worst, trans_cost_best, penal_cost_best = np.amin( np.asarray(results), axis=0) return type1ServiceLevel_mean, type2ServiceLevel_mean, type1ServiceLevel_worst, type2ServiceLevel_worst, trans_cost_mean, penal_cost_mean
def triangular_simulation(a, demand, Z, I, mode, num_plants, num_demand, cishu=500): print('--------triangular_simulation----------') lower_demand = demand[0] mean_demand = demand[1] upper_demand = demand[2] total_CC = 0 total_fillrate = 0 total_arcs = 0 plants = range(num_plants) demand = range(num_demand) for n in range(cishu): realized_demand = [0] * len(lower_demand) for k in range(len(realized_demand)): realized_demand[k] = round( random.triangular(lower_demand[k], upper_demand[k], mean_demand[k] * mode)) #申明Fillrate中Z(w)值的那个模型 evaluation_problem = grb.Model('evaluation_problem') evaluation_problem.setParam('OutputFlag', 0) evaluation_problem.modelSense = grb.GRB.MAXIMIZE #申明评估模型的变量 evaluation_X = evaluation_problem.addVars(plants, demand, obj=[[1 for j in demand] for i in plants], vtype=grb.GRB.INTEGER, name='evaluation_X') #添加评估模型的约束 #约束1 for i in plants: expr = 0 for j in demand: expr = expr + evaluation_X[i, j] evaluation_problem.addConstr(expr <= I[i]) del expr #约束2 for j in demand: expr = 0 for i in plants: expr = expr + evaluation_X[i, j] evaluation_problem.addConstr(expr <= realized_demand[j]) del expr #约束3 其实是paper中的4,gurobi自带正数约束 for i in plants: for j in demand: if round(a[i, j] * Z[i]) == 0: evaluation_problem.addConstr(evaluation_X[i, j] <= 0) #求解评估模型,并求出fillrate 还要输出 evaluation_problem.optimize() #########################运输完成了 #########################计算用上的道路arcs arcs = 0 for i in plants: for j in demand: arcs = (round(evaluation_X[i, j].x) > 0.1) + arcs ########################CC的值########################## ##################来看是否满足cutting plane的LP #申明CC问题 CC_problem = grb.Model('CC_problem') CC_problem.setParam('OutputFlag', 0) #申明CC问题的变量 CC_x = CC_problem.addVars(demand, vtype=grb.GRB.BINARY, name='CC_x') CC_y = CC_problem.addVars(plants, vtype=grb.GRB.BINARY, name='CC_y') #设置目标函数 expr1 = 0 expr2 = 0 for i in plants: expr1 = expr1 + CC_y[i] * I[i] for j in demand: expr2 = expr2 + realized_demand[j] * CC_x[j] CC_problem.setObjective(expr1 - expr2, grb.GRB.MINIMIZE) del expr1 del expr2 #载入CC问题的约束 #约束1 for i in plants: for j in demand: if round(a[i, j] * round(Z[i])) == 1: CC_problem.addConstr(CC_y[i] >= CC_x[j]) #解CC问题 CC_problem.optimize() total_CC += (CC_problem.ObjVal >= 0) total_fillrate += evaluation_problem.ObjVal / sum(realized_demand) total_arcs += arcs if n % 100 == 0: print(n) eva_X = np.zeros(shape=(num_plants, num_demand)) for i in plants: for i in demand: eva_X[i, j] = round(evaluation_X[i, j].x) return eva_X, total_arcs / cishu, total_CC / cishu, total_fillrate / cishu
def uniform_simulation(a, demand, Z, I, num_plants, num_demand, cishu=500): print('--------uniform_simulation----------') lower_demand = demand[0] upper_demand = demand[2] plants = range(num_plants) demand = range(num_demand) results = [] for n in range(cishu): realized_demand = [0] * len(lower_demand) for k in range(len(realized_demand)): realized_demand[k] = round( random.randint(lower_demand[k], upper_demand[k])) #申明Fillrate中Z(w)值的那个模型 evaluation_problem = grb.Model('evaluation_problem') evaluation_problem.setParam('OutputFlag', 0) evaluation_problem.modelSense = grb.GRB.MAXIMIZE evaluation_X = evaluation_problem.addVars(plants, demand, obj=[[1 for j in demand] for i in plants], vtype=grb.GRB.INTEGER, name='evaluation_X') #添加评估模型的约束 #约束1 for i in plants: expr = 0 for j in demand: expr = expr + evaluation_X[i, j] evaluation_problem.addConstr(expr <= I[i]) del expr #约束2 for j in demand: expr = 0 for i in plants: expr = expr + evaluation_X[i, j] evaluation_problem.addConstr(expr <= realized_demand[j]) del expr #约束3 其实是paper中的4,gurobi自带正数约束 for i in plants: for j in demand: if round(a[i, j] * Z[i]) == 0: evaluation_problem.addConstr(evaluation_X[i, j] <= 0) #求解评估模型,并求出fillrate 还要输出 evaluation_problem.optimize() type1ServiceLevel = sum([ np.abs( sum([evaluation_X[i, j].x for i in plants]) - realized_demand[j]) <= 0.005 for j in demand ]) / num_demand type2ServiceLevel = sum( [sum([evaluation_X[i, j].x for i in plants]) for j in demand]) / sum(realized_demand) results.append([type1ServiceLevel, type2ServiceLevel]) return np.mean(np.asarray(results), axis=0)
def simulationWithCost(a, demand, Z, I, num_plants, num_demand, tranposrtation_cost, penalty_cost, cishu=500): print('--------Mixed_distribution_simulation----------') #lower_demand = demand[0] #mean_demand = demand[1] #upper_demand = demand[2] realized_demand = np.zeros(shape=(cishu, num_demand)) realized_demand = demand plants = range(num_plants) demand = range(num_demand) results = [] for n in range(cishu): oneDemandScenario = realized_demand[n] #申明Fillrate中Z(w)值的那个模型 evaluation_problem = grb.Model('evaluation_problem') evaluation_problem.setParam('OutputFlag', 0) evaluation_problem.modelSense = grb.GRB.MINIMIZE evaluation_X = evaluation_problem.addVars(plants, demand, vtype=grb.GRB.CONTINUOUS, name='evaluation_X') objFunc_penal = grb.quicksum([ penalty_cost[j] * (oneDemandScenario[j] - grb.quicksum([evaluation_X[i, j] for i in plants])) for j in demand ]) objFunc_trans = grb.quicksum(evaluation_X[i, j] * tranposrtation_cost[i, j] for i in plants for j in demand) evaluation_problem.setObjective(objFunc_penal + objFunc_trans) #添加评估模型的约束 #约束1 for i in plants: expr = 0 for j in demand: expr = expr + evaluation_X[i, j] evaluation_problem.addConstr(expr <= I[i]) del expr #约束2 for j in demand: expr = 0 for i in plants: expr = expr + evaluation_X[i, j] evaluation_problem.addConstr(expr <= oneDemandScenario[j]) del expr #约束3 其实是paper中的4,gurobi自带正数约束 for i in plants: for j in demand: if round(a[i, j] * Z[i]) == 0: evaluation_problem.addConstr(evaluation_X[i, j] <= 0) #求解评估模型,并求出fillrate 还要输出 evaluation_problem.optimize() #transportation trans = np.zeros(shape=(num_plants, num_demand)) for i in plants: for j in demand: trans[i, j] = evaluation_X[i, j].x type1ServiceLevel = sum( np.abs(trans.sum(axis=0) - oneDemandScenario) <= 0.0005) / num_demand type2ServiceLevel = trans.sum() / sum(oneDemandScenario) trans_cost = (trans * tranposrtation_cost).sum() penal_cost = sum( (oneDemandScenario - trans.sum(axis=0)) * penalty_cost) results.append( [type1ServiceLevel, type2ServiceLevel, trans_cost, penal_cost]) type1ServiceLevel_mean, type2ServiceLevel_mean, trans_cost_mean, penal_cost_mean = np.mean( np.asarray(results), axis=0) type1ServiceLevel_worst, type2ServiceLevel_worst, trans_cost_best, penal_cost_best = np.amin( np.asarray(results), axis=0) return type1ServiceLevel_mean, type2ServiceLevel_mean, type1ServiceLevel_worst, type2ServiceLevel_worst, trans_cost_mean, penal_cost_mean
num_demand = [] # length that every buyer need L = [] for amount, l in zip(demand['Amount'].values, demand['Length'].values): num_demand.append(int(amount)) L.append(l) # buyer = range(len(num_demand)) max_material = range(sum(num_demand)) #General model #estabilish model m = grb.Model('model1') m.modelSense = grb.GRB.MINIMIZE m.setParam('OutputFlag', 0) # addvars X = m.addVars(max_material, buyer, vtype=grb.GRB.INTEGER, ub=1, lb=0, obj=0) Y = m.addVars(max_material, vtype=grb.GRB.INTEGER, ub=1, lb=0, obj=1) #add constraints #1rt : aggregated cutted length should less than total length for i in max_material: expr = 0 for j in buyer: expr = X[i, j] * L[j] + expr m.addConstr(expr <= Y[i] * length)
def hoeffding_design(cost, demand, a, num_plants, num_demand, service_level=0.1): fixed_cost = cost[0] holding_cost = cost[1] lower_demand = demand[0] mean_demand = demand[1] upper_demand = demand[2] plants = range(num_plants) demand = range(num_demand) inventory = range(num_plants) #记录每次加入的约束是Case1 or Case2 or Others0 constraintType = [] #记录每次迭代时候的objvalue iterValue = [] SNum = [] #------------申明主问题-----------# #申明主模型 master_problem = grb.Model('master_problem') master_problem.setParam('OutputFlag', 0) master_problem.modelSense = grb.GRB.MINIMIZE #申明决策变量 obj=***就表明了该组变量在目标函数中的系数 ####这一块参考gurobi给的例子:facility.py I = master_problem.addVars(inventory, vtype=grb.GRB.INTEGER, obj=holding_cost, name='I') Z = master_problem.addVars(plants, vtype=grb.GRB.BINARY, obj=fixed_cost, name='Z') #----------载入各种约束-----------# #利用hoeffding inequality计算总库存水平 temp_sum = sum((upper_demand - lower_demand)**2) TI = math.ceil(mean_demand.sum() + math.sqrt(-math.log(service_level) * temp_sum / 2)) del temp_sum #载入chance constraints #至少有 demand个约束(至少每个需求点的需求,都能被和它相连的supplier满足吧) for j in demand: expr = sum(a[:, j] * I.values()) master_problem.addQConstr( expr >= min(upper_demand[j], TI - (lower_demand.sum() - lower_demand[j]))) del expr #记录加入的约束的类型 SNum.append(1) if upper_demand[j] < TI - (lower_demand.sum() - lower_demand[j]): constraintType.append(1) if upper_demand[j] > TI - (lower_demand.sum() - lower_demand[j]): constraintType.append(2) if upper_demand[j] == TI - (lower_demand.sum() - lower_demand[j]): constraintType.append(3) #载入约束3-----Ii<=M*Zi M = upper_demand.sum() master_problem.addConstrs(I[i] <= M * Z[i] for i in plants) for i in plants: #记录加入的约束的类型 constraintType.append(0) SNum.append(0) #total inventory的约束 master_problem.addConstr(sum(I.values()) == TI) constraintType.append(0) #记录加入的约束的类型 SNum.append(0) #------------------开始迭代主问题------------------------------------# #-------------------------------------------------------------------# add_constraints_time = 0 time_start = time.clock() while True: #解主问题 master_problem.optimize() #确定主问题解的状态 if master_problem.status == 3: break elif master_problem.status == 2: print('Master_Val:', master_problem.ObjVal) iterValue.append(master_problem.ObjVal) #-------------开始子问题---------------# #申明子问题 sub_problem = grb.Model('sub_problem') sub_problem.setParam('OutputFlag', 0) #申明子问题的变量 x = sub_problem.addVars(demand, vtype=grb.GRB.BINARY, name='x') y = sub_problem.addVars(plants, vtype=grb.GRB.BINARY, name='y') z = sub_problem.addVar(vtype=grb.GRB.CONTINUOUS, name='z') #设置目标函数 expr1 = grb.quicksum([y[i] * I[i].x for i in plants]) expr2 = grb.quicksum([upper_demand[j] * x[j] for j in demand]) sub_problem.setObjective(expr1 - expr2 + z, grb.GRB.MINIMIZE) del expr1 del expr2 #载入子问题的约束 #z>0约束 sub_problem.addConstr(z >= 0) #子问题约束1 expr1 = sum(upper_demand * x.values()) expr2 = grb.quicksum( [lower_demand[j] * (1 - x[j]) for j in demand]) sub_problem.addConstr(z >= expr1 - TI + expr2) del expr1 del expr2 #子问题约束2 for i in plants: for j in demand: if round(a[i, j]) == 1: sub_problem.addConstr(y[i] >= x[j]) #解子问题 sub_problem.optimize() #判断子问题的目标函数值是否为非负数,若是,则主问题得到了最优解,break;否则加入新的约束到主问题中 if sub_problem.ObjVal >= -0.001: break else: print(sub_problem.ObjVal) expr1 = grb.quicksum([I[i] * y[i].x for i in plants]) expr2 = sum([upper_demand[j] * x[j].x for j in demand]) expr3 = sum([lower_demand[j] * (1 - x[j].x) for j in demand]) temp_expr = (expr1 >= min(expr2, TI - expr3)) master_problem.addConstr(temp_expr) #加新的约束到主问题中 #记录加入的约束的类型 if expr2 < TI - expr3: constraintType.append(1) if expr2 > TI - expr3: constraintType.append(2) if expr2 == TI - expr3: constraintType.append(3) SNum.append(sum([x[j].x for j in demand])) del expr1 del expr2 del expr3 del temp_expr add_constraints_time += 1 time_end = time.clock() ################################到这里图就设计好了################################### ################################到这里图就设计好了################################### #输出一些图的参数(仓库数,道路数,总库存=TI) if master_problem.status == 2: I_return = [] Z_return = [] open_DC = 0 for i in plants: I_return.append(I[i].x) Z_return.append(Z[i].x) open_DC = Z[i].x + open_DC p = TI return master_problem, constraintType, iterValue, SNum, [ 'hoeffding', open_DC, I_return, Z_return, p, p / TI, master_problem.ObjVal, time_end - time_start, add_constraints_time, 'optimal' ] elif master_problem.status == 3: return master_problem, constraintType, iterValue, SNum, [ '-', '-', '-', '-', '-', '-', '-', '-', '-', 'infeasible' ]
def small_big_design_multiitem(cost, demand, a, num_plants, num_demand, s, S, weight, service_level=0.1, mode='set'): add_constraints_time = 0 fixed_cost = cost[0] holding_cost = cost[1] lower_demand = demand[0] mean_demand = demand[1] upper_demand = demand[2] items = range(lower_demand.shape[0]) plants = range(num_plants) demand = range(num_demand) constraintType = [] iterValue = [] iterValue_small = [] iterValue_big = [] # ---- 申明主问题 #申明主模型 master_problem = grb.Model('master_problem') master_problem.setParam('OutputFlag', 0) master_problem.modelSense = grb.GRB.MINIMIZE #申明决策变量 obj=***就表明了该组变量在目标函数中的系数 ####这一块参考gurobi给的例子:facility.py I = master_problem.addVars(items, plants, vtype=grb.GRB.CONTINUOUS, obj=holding_cost, name='I') Z = master_problem.addVars(plants, vtype=grb.GRB.BINARY, obj=fixed_cost, name='Z') # ---- 载入各种约束 #额外算的值 TI = np.zeros(shape=lower_demand.shape[0]) for k in items: temp_sum = sum((upper_demand[k] - lower_demand[k])**2) TI[k] = math.ceil(mean_demand[k].sum() + math.sqrt(-math.log(service_level) * temp_sum / 2)) del temp_sum #载入chance constraints #至少有 demand个约束(至少每个需求点的需求,都能被和它相连的supplier满足吧) #这里是small set的约束 for k in items: for j in demand: expr = sum(a[:, j] * I.values()[13 * k:13 * (k + 1)]) master_problem.addConstr(expr >= upper_demand[k, j]) del expr constraintType.append('small') #这里是big set的约束 #要求|S|>25 (某数),最直观的的是取30时候,此时不属于这个集合的点是空集 #所以没有约束。 #第二个的约束去子问题中迭代加入 expr = 0 del expr #载入约束3-----Ii<=M*Zi M = upper_demand.sum() master_problem.addConstrs(I[k, i] <= M * Z[i] for k in items for i in plants) for i in plants: constraintType.append('others') # ---- 开始迭代主问题 time_start = time.clock() while True: #解主问题 master_problem.optimize() #确定主问题解的状态 if master_problem.status == 3: iterValue.append(master_problem.ObjVal) break elif master_problem.status == 2: print('master_Value:', master_problem.ObjVal) iterValue.append(master_problem.ObjVal) # ---- 开始子问题 IterSubObjVal = np.zeros(shape=(lower_demand.shape[0], 2)) IterX = np.zeros(shape=(lower_demand.shape[0], lower_demand.shape[1], 2)) IterY = np.zeros(shape=(lower_demand.shape[0], lower_demand.shape[1], 2)) # K-th item: for k in items: #申明small set的子问题----sub_problem1 sub_problem1 = grb.Model('sub_problem1') sub_problem1.setParam('OutputFlag', 0) #申明子问题的变量 x1 = sub_problem1.addVars(demand, vtype=grb.GRB.BINARY, name='x1') y1 = sub_problem1.addVars(plants, vtype=grb.GRB.BINARY, name='y1') #设置目标函数 expr1 = grb.quicksum([y1[i] * I[k, i].x for i in plants]) expr2 = sum(upper_demand[k] * x1.values()) #for j in demand: # expr2 = expr2 + upper_demand[j] * x1[j] sub_problem1.setObjective(expr1 - expr2, grb.GRB.MINIMIZE) del expr1 del expr2 #载入子问题的约束 #子问题约束1 expr = sum(x1.values()) sub_problem1.addConstr(expr <= s) del expr #子问题约束2, for i in plants: for j in demand: if round(a[i, j]) == 1: sub_problem1.addConstr(y1[i] >= x1[j]) #解子问题 sub_problem1.optimize() #申明big set的子问题----sub_problem2 ----------- #big set #big set #big set sub_problem2 = grb.Model('sub_problem1') sub_problem2.setParam('OutputFlag', 0) #申明子问题的变量 x2 = sub_problem2.addVars(demand, vtype=grb.GRB.BINARY, name='x2') y2 = sub_problem2.addVars(plants, vtype=grb.GRB.BINARY, name='y2') #设置目标函数 expr1 = grb.quicksum([(1 - y2[i]) * I[k, i].x for i in plants]) expr2 = grb.quicksum( [lower_demand[k, j] * (1 - x2[j]) for j in demand]) sub_problem2.setObjective(expr2 - expr1, grb.GRB.MINIMIZE) del expr1 del expr2 #载入子问题的约束 #子问题约束1 expr = grb.quicksum(x2.values()) sub_problem2.addConstr(expr >= S) del expr #子问题约束2, for i in plants: for j in demand: if round(a[i, j]) == 1: sub_problem2.addConstr(y2[i] >= x2[j]) #解子问题 sub_problem2.optimize() IterSubObjVal[k, 0] = sub_problem1.ObjVal IterSubObjVal[k, 1] = sub_problem2.ObjVal for j in demand: IterX[k, j, 0] = x1[j].x IterX[k, j, 1] = x2[j].x for i in plants: IterY[k, i, 0] = y1[i].x IterY[k, i, 1] = y2[i].x #判断子问题的目标函数值是否为非负数,若是,则主问题得到了最优解,break;否则加入新的约束到主问题中 if all(IterSubObjVal.reshape(6) >= -0.01): iterValue_small.append(IterSubObjVal[k, 0] for k in items) iterValue_big.append(IterSubObjVal[k, 1] for k in items) break else: for k in items: if IterSubObjVal[k, 0] < -0.001: print('small_set:', IterSubObjVal[k, 0]) iterValue_small.append(IterSubObjVal[k, 0]) expr1 = 0 expr2 = 0 a_temp = [0] * num_plants for j in demand: a_temp = IterX[k, j, 0] * a[:, j] + a_temp expr2 = upper_demand[k, j] * IterX[k, j, 0] + expr2 for i in plants: if round(a_temp[i]) != 0: expr1 = expr1 + round(a_temp[i]) / round( a_temp[i]) * I[k, i] temp_expr = expr1 >= expr2 master_problem.addConstr(temp_expr) #加新的约束到主问题中 constraintType.append('small') del expr1 del expr2 del temp_expr del a_temp add_constraints_time += 1 else: iterValue_small.append(np.nan) if IterSubObjVal[k, 1] < -0.001: print('big_set:', IterSubObjVal[k, 1]) iterValue_big.append(IterSubObjVal[k, 1]) expr1 = 0 expr2 = 0 a_temp = [0] * num_plants for j in demand: a_temp = IterX[k, j, 1] * a[:, j] + a_temp expr2 = lower_demand[k, j] * ( int(not IterX[k, j, 1])) + expr2 for i in plants: expr1 = expr1 + int(not a_temp[i]) * I[k, i] temp_expr = expr1 <= expr2 master_problem.addConstr(temp_expr) #加新的约束到主问题中 constraintType.append('big') del expr1 del expr2 del temp_expr del a_temp add_constraints_time += 1 else: iterValue_big.append(np.nan) time_end = time.clock() if master_problem.status == 2: open_DC = sum([Z[i].x for i in plants]) I_return = [[I[k, i].x for i in plants] for k in items] Z_return = [Z[i].x for i in plants] p = [sum(I[k, i].x for i in plants) for k in items] return master_problem, constraintType, iterValue, iterValue_small, iterValue_big, [ s, open_DC, I_return, Z_return, p, p / TI, master_problem.ObjVal, time_end - time_start, add_constraints_time, 'optimal' ] elif master_problem.status == 3: return master_problem, constraintType, iterValue, iterValue_small, iterValue_big, [ '-', '-', '-', '-', '-', '-', '-', '-', '-', 'infeasible' ]
def small_big_fulldesign(cost, demand, a, num_plants, num_demand, s, S, weight, service_level=0.1): ''' 把exponential多的约束全部加入到模型中,解一个大模型 ''' fixed_cost = np.asarray(cost[0]) holding_cost = np.asarray(cost[1]) lower_demand = demand[0] mean_demand = demand[1] upper_demand = demand[2] inventory = range(num_plants) plants = range(num_plants) demand = range(num_demand) #------------申明主问题-----------# #申明主模型 master_problem = grb.Model('master_problem') master_problem.setParam('OutputFlag', 0) master_problem.modelSense = grb.GRB.MINIMIZE #申明决策变量 obj=***就表明了该组变量在目标函数中的系数 ####这一块参考gurobi给的例子:facility.py I = master_problem.addVars(inventory, vtype=grb.GRB.CONTINUOUS, obj=holding_cost, name='I') Z = master_problem.addVars(plants, vtype=grb.GRB.BINARY, obj=fixed_cost, name='Z') #----------载入各种约束-----------# #额外算的值 temp_sum = sum((upper_demand - lower_demand)**2) TI = math.ceil(mean_demand.sum() + math.sqrt(-math.log(service_level) * temp_sum / 2)) del temp_sum #载入chance constraints #至少有 demand个约束(至少每个需求点的需求,都能被和它相连的supplier满足吧) #这里是small set的约束 for k in range(1, s + 1): for nodeSet in itertools.combinations(range(num_demand), k): expr = sum((a[:, nodeSet].sum(axis=1) >= 1) * I.values()) master_problem.addConstr(expr >= sum(upper_demand[j] for j in nodeSet)) del expr print('Small=={},约束添加完成'.format(k)) #这里是big set的约束 for k in range(S + 1, num_demand + 1): for nodeSet in itertools.combinations(range(num_demand), k): nonNodeSet = [j for j in range(num_demand) if j not in nodeSet] nonAdjacentNodeSet = np.where(a[:, nodeSet].sum(axis=1) == 0)[0] expr_I = sum(I[i] for i in nonAdjacentNodeSet) expr_DL = sum(lower_demand[j] for j in nonNodeSet) if nonAdjacentNodeSet.size != 0: #if nonAdjacentNodeSet.size==0, expr_i==0,下面的等式始终成立 master_problem.addConstr(expr_I <= expr_DL) del expr_I, expr_DL print('Big=={},约束添加完成'.format(k)) #载入约束3-----Ii<=M*Zi M = upper_demand.sum() master_problem.addConstrs(I[i] <= M * Z[i] for i in plants) #求解 master_problem.optimize() return master_problem, { '# of Open DC': sum(Z.values()), 'FSC': sum(Z.values() * fixed_cost) + sum(I.values() * holding_cost), 'Inventory': I.values(), 'Total Inventory': sum(I.values()) }
def small_big_design(cost, demand, a, num_plants, num_demand, s, S, weight, service_level=0.1, mode='set'): if mode == 'set': add_constraints_time = 0 fixed_cost = cost[0] holding_cost = cost[1] lower_demand = demand[0] mean_demand = demand[1] upper_demand = demand[2] inventory = range(num_plants) plants = range(num_plants) demand = range(num_demand) constraintType = [] iterValue = [] iterValue_small = [] iterValue_big = [] #------------申明主问题-----------# #申明主模型 master_problem = grb.Model('master_problem') master_problem.setParam('OutputFlag', 0) master_problem.modelSense = grb.GRB.MINIMIZE #申明决策变量 obj=***就表明了该组变量在目标函数中的系数 ####这一块参考gurobi给的例子:facility.py I = master_problem.addVars(inventory, vtype=grb.GRB.CONTINUOUS, obj=holding_cost, name='I') Z = master_problem.addVars(plants, vtype=grb.GRB.BINARY, obj=fixed_cost, name='Z') #----------载入各种约束-----------# #额外算的值 temp_sum = sum((upper_demand - lower_demand)**2) TI = math.ceil(mean_demand.sum() + math.sqrt(-math.log(service_level) * temp_sum / 2)) del temp_sum #载入chance constraints #至少有 demand个约束(至少每个需求点的需求,都能被和它相连的supplier满足吧) #这里是small set的约束 for j in demand: expr = sum(a[:, j] * I.values()) master_problem.addConstr(expr >= upper_demand[j]) del expr constraintType.append('small') #这里是big set的约束 #要求|S|>25 (某数),最直观的的是取30时候,此时不属于这个集合的点是空集 #所以没有约束。 #第二个的约束去子问题中迭代加入 expr = 0 del expr #载入约束3-----Ii<=M*Zi M = upper_demand.sum() master_problem.addConstrs(I[i] <= M * Z[i] for i in plants) for i in plants: constraintType.append('others') #------------------开始迭代主问题------------------------------------# #-------------------------------------------------------------------# time_start = time.clock() while True: #解主问题 master_problem.optimize() #确定主问题解的状态 if master_problem.status == 3: iterValue.append(master_problem.ObjVal) break elif master_problem.status == 2: print('master_Value:', master_problem.ObjVal) iterValue.append(master_problem.ObjVal) #-------------开始子问题---------------# #申明small set的子问题----sub_problem1 sub_problem1 = grb.Model('sub_problem1') sub_problem1.setParam('OutputFlag', 0) #申明子问题的变量 x1 = sub_problem1.addVars(demand, vtype=grb.GRB.BINARY, name='x1') y1 = sub_problem1.addVars(plants, vtype=grb.GRB.BINARY, name='y1') #设置目标函数 expr1 = grb.quicksum([y1[i] * I[i].x for i in plants]) expr2 = sum(upper_demand * x1.values()) #for j in demand: # expr2 = expr2 + upper_demand[j] * x1[j] sub_problem1.setObjective(expr1 - expr2, grb.GRB.MINIMIZE) del expr1 del expr2 #载入子问题的约束 #子问题约束1 expr = sum(x1.values()) sub_problem1.addConstr(expr <= s) del expr #子问题约束2, for i in plants: for j in demand: if round(a[i, j]) == 1: sub_problem1.addConstr(y1[i] >= x1[j]) #解子问题 sub_problem1.optimize() #申明big set的子问题----sub_problem2 ----------- #big set #big set #big set sub_problem2 = grb.Model('sub_problem1') sub_problem2.setParam('OutputFlag', 0) #申明子问题的变量 x2 = sub_problem2.addVars(demand, vtype=grb.GRB.BINARY, name='x2') y2 = sub_problem2.addVars(plants, vtype=grb.GRB.BINARY, name='y2') #设置目标函数 expr1 = grb.quicksum([(1 - y2[i]) * I[i].x for i in plants]) expr2 = grb.quicksum( [lower_demand[j] * (1 - x2[j]) for j in demand]) sub_problem2.setObjective(expr2 - expr1, grb.GRB.MINIMIZE) del expr1 del expr2 #载入子问题的约束 #子问题约束1 expr = grb.quicksum(x2.values()) sub_problem2.addConstr(expr >= S) del expr #子问题约束2, for i in plants: for j in demand: if round(a[i, j]) == 1: sub_problem2.addConstr(y2[i] >= x2[j]) #解子问题 sub_problem2.optimize() #判断子问题的目标函数值是否为非负数,若是,则主问题得到了最优解,break;否则加入新的约束到主问题中 if sub_problem1.ObjVal >= -0.01 and sub_problem2.ObjVal >= -0.01: iterValue_small.append(sub_problem1.ObjVal) iterValue_big.append(sub_problem2.ObjVal) break else: if sub_problem1.ObjVal < -0.001: print('small_set:', sub_problem1.ObjVal) iterValue_small.append(sub_problem1.ObjVal) expr1 = 0 expr2 = 0 a_temp = [0] * num_plants for j in demand: a_temp = x1[j].x * a[:, j] + a_temp expr2 = upper_demand[j] * x1[j].x + expr2 for i in plants: if round(a_temp[i]) != 0: expr1 = expr1 + round(a_temp[i]) / round( a_temp[i]) * I[i] temp_expr = expr1 >= expr2 master_problem.addConstr(temp_expr) #加新的约束到主问题中 constraintType.append('small') del expr1 del expr2 del temp_expr del a_temp add_constraints_time += 1 else: iterValue_small.append(np.nan) if sub_problem2.ObjVal < -0.001: print('big_set:', sub_problem2.ObjVal) iterValue_big.append(sub_problem2.ObjVal) expr1 = 0 expr2 = 0 a_temp = [0] * num_plants for j in demand: a_temp = x2[j].x * a[:, j] + a_temp expr2 = lower_demand[j] * ( int(not x2[j].x)) + expr2 for i in plants: expr1 = expr1 + int(not a_temp[i]) * I[i] temp_expr = expr1 <= expr2 master_problem.addConstr(temp_expr) #加新的约束到主问题中 constraintType.append('big') del expr1 del expr2 del temp_expr del a_temp add_constraints_time += 1 else: iterValue_big.append(np.nan) time_end = time.clock() if master_problem.status == 2: I_return = [] Z_return = [] p = 0 open_DC = 0 for i in plants: open_DC = open_DC + Z[i].x p = p + I[i].x I_return.append(I[i].x) Z_return.append(Z[i].x) return master_problem, constraintType, iterValue, iterValue_small, iterValue_big, [ s, open_DC, I_return, Z_return, p, p / TI, master_problem.ObjVal, time_end - time_start, add_constraints_time, 'optimal' ] elif master_problem.status == 3: return master_problem, constraintType, iterValue, iterValue_small, iterValue_big, [ '-', '-', '-', '-', '-', '-', '-', '-', '-', 'infeasible' ] if mode == 'weight': add_constraints_time = 0 fixed_cost = cost[0] holding_cost = cost[1] lower_demand = demand[0] mean_demand = demand[1] upper_demand = demand[2] inventory = range(num_plants) plants = range(num_plants) demand = range(num_demand) #------------申明主问题-----------# #申明主模型 master_problem = grb.Model('master_problem') master_problem.setParam('OutputFlag', 0) master_problem.modelSense = grb.GRB.MINIMIZE #申明决策变量 obj=***就表明了该组变量在目标函数中的系数 ####这一块参考gurobi给的例子:facility.py I = master_problem.addVars(inventory, vtype=grb.GRB.INTEGER, obj=holding_cost, name='I') Z = master_problem.addVars(plants, vtype=grb.GRB.BINARY, obj=fixed_cost, name='Z') #----------载入各种约束-----------# #额外算的值 temp_sum = 0 for j in demand: temp_sum += (upper_demand[j] - lower_demand[j]) * (upper_demand[j] - lower_demand[j]) TI = math.ceil(mean_demand.sum() + math.sqrt(-math.log(service_level) * temp_sum / 2)) del temp_sum #载入chance constraints #没有约束。 #第二个的约束去子问题中迭代加入 expr = 0 del expr #载入约束3-----Ii<=M*Zi M = upper_demand.sum() master_problem.addConstrs(I[i] <= M * Z[i] for i in plants) #------------------开始迭代主问题------------------------------------# #-------------------------------------------------------------------# time_start = time.clock() while True: #解主问题 master_problem.optimize() #确定主问题解的状态 if master_problem.status == 3: break elif master_problem.status == 2: #-------------开始子问题---------------# #申明small set的子问题----sub_problem1 sub_problem1 = grb.Model('sub_problem1') sub_problem1.setParam('OutputFlag', 0) #申明子问题的变量 x1 = sub_problem1.addVars(demand, vtype=grb.GRB.BINARY, name='x1') y1 = sub_problem1.addVars(plants, vtype=grb.GRB.BINARY, name='y1') #设置目标函数 expr1 = 0 expr2 = 0 for i in plants: expr1 = expr1 + y1[i] * I[i].x for j in demand: expr2 = expr2 + upper_demand[j] * x1[j] sub_problem1.setObjective(expr1 - expr2, grb.GRB.MINIMIZE) del expr1 del expr2 #载入子问题的约束 #子问题约束1 sub_problem1.addConstr( grb.quicksum(x1[j] * upper_demand[j] for j in demand) <= weight * M) #子问题约束2, for i in plants: for j in demand: if round(a[i, j]) == 1: sub_problem1.addConstr(y1[i] >= x1[j]) #解子问题 sub_problem1.optimize() #申明big set的子问题----sub_problem2 ----------- #big set #big set #big set sub_problem2 = grb.Model('sub_problem1') sub_problem2.setParam('OutputFlag', 0) #申明子问题的变量 x2 = sub_problem2.addVars(demand, vtype=grb.GRB.BINARY, name='x2') y2 = sub_problem2.addVars(plants, vtype=grb.GRB.BINARY, name='y2') #设置目标函数 expr1 = 0 expr2 = 0 for i in plants: expr1 = expr1 + (1 - y2[i]) * I[i].x for j in demand: expr2 = expr2 + lower_demand[j] * (1 - x2[j]) sub_problem2.setObjective(expr2 - expr1, grb.GRB.MINIMIZE) del expr1 del expr2 #载入子问题的约束 #子问题约束1 sub_problem2.addConstr( grb.quicksum(x1[j] * lower_demand[j] for j in demand) >= (1 - weight) * M) #子问题约束2, for i in plants: for j in demand: if round(a[i, j]) == 1: sub_problem2.addConstr(y2[i] >= x2[j]) #解子问题 sub_problem2.optimize() #判断子问题的目标函数值是否为非负数,若是,则主问题得到了最优解,break;否则加入新的约束到主问题中 if sub_problem1.ObjVal >= 0 and sub_problem2.ObjVal >= 0: break else: if sub_problem1.ObjVal < -0.0001: print('small_set:', sub_problem1.ObjVal) expr1 = 0 expr2 = 0 a_temp = [0] * num_plants for j in demand: a_temp = x1[j].x * a[:, j] + a_temp expr2 = upper_demand[j] * x1[j].x + expr2 for i in plants: if round(a_temp[i]) != 0: expr1 = expr1 + round(a_temp[i]) / round( a_temp[i]) * I[i] temp_expr = expr1 >= expr2 master_problem.addConstr(temp_expr) #加新的约束到主问题中 del expr1 del expr2 del temp_expr del a_temp add_constraints_time += 1 if sub_problem2.ObjVal < -0.0001: print('big_set:', sub_problem2.ObjVal) expr1 = 0 expr2 = 0 a_temp = [0] * num_plants for j in demand: a_temp = x2[j].x * a[:, j] + a_temp expr2 = lower_demand[j] * ( int(not x2[j].x)) + expr2 for i in plants: expr1 = expr1 + int(not a_temp[i]) * I[i] temp_expr = expr1 <= expr2 master_problem.addConstr(temp_expr) #加新的约束到主问题中 del expr1 del expr2 del temp_expr del a_temp add_constraints_time += 1 time_end = time.clock() if master_problem.status == 2: I_return = [] Z_return = [] p = 0 open_DC = 0 for i in plants: open_DC = open_DC + Z[i].x p = p + I[i].x I_return.append(I[i].x) Z_return.append(Z[i].x) return s, open_DC, I_return, Z_return, p, p / TI, master_problem.ObjVal, time_end - time_start, add_constraints_time, 'optimal' elif master_problem.status == 3: return '-', '-', '-', '-', '-', '-', '-', '-', '-', 'infeasible' if mode == 'both': add_constraints_time = 0 fixed_cost = cost[0] holding_cost = cost[1] lower_demand = demand[0] mean_demand = demand[1] upper_demand = demand[2] inventory = range(num_plants) plants = range(num_plants) demand = range(num_demand) #------------申明主问题-----------# #申明主模型 master_problem = grb.Model('master_problem') master_problem.setParam('OutputFlag', 0) master_problem.modelSense = grb.GRB.MINIMIZE #申明决策变量 obj=***就表明了该组变量在目标函数中的系数 ####这一块参考gurobi给的例子:facility.py I = master_problem.addVars(inventory, vtype=grb.GRB.INTEGER, obj=holding_cost, name='I') Z = master_problem.addVars(plants, vtype=grb.GRB.BINARY, obj=fixed_cost, name='Z') #----------载入各种约束-----------# #额外算的值 temp_sum = 0 for j in demand: temp_sum += (upper_demand[j] - lower_demand[j]) * (upper_demand[j] - lower_demand[j]) TI = math.ceil(mean_demand.sum() + math.sqrt(-math.log(service_level) * temp_sum / 2)) del temp_sum #载入chance constraints #至少有 demand个约束(至少每个需求点的需求,都能被和它相连的supplier满足吧) #这里是small set的约束 for j in demand: expr = 0 for i in plants: expr = a[i, j] * I[i] + expr master_problem.addQConstr(expr >= upper_demand[j]) del expr #这里是big set的约束 #要求|S|>25 (某数),最直观的的是取30时候,此时不属于这个集合的点是空集 #所以没有约束。 #第二个的约束去子问题中迭代加入 expr = 0 del expr #载入约束3-----Ii<=M*Zi M = upper_demand.sum() master_problem.addConstrs(I[i] <= M * Z[i] for i in plants) #------------------开始迭代主问题------------------------------------# #-------------------------------------------------------------------# time_start = time.clock() while True: #解主问题 master_problem.optimize() #确定主问题解的状态 if master_problem.status == 3: break elif master_problem.status == 2: #-------------开始子问题---------------# ''' 2个和set大小有关的子问题 ''' #申明small set的子问题----sub_problem1 sub_problem1 = grb.Model('sub_problem1') sub_problem1.setParam('OutputFlag', 0) #申明子问题的变量 x1 = sub_problem1.addVars(demand, vtype=grb.GRB.BINARY, name='x1') y1 = sub_problem1.addVars(plants, vtype=grb.GRB.BINARY, name='y1') #设置目标函数 expr1 = 0 expr2 = 0 for i in plants: expr1 = expr1 + y1[i] * I[i].x for j in demand: expr2 = expr2 + upper_demand[j] * x1[j] sub_problem1.setObjective(expr1 - expr2, grb.GRB.MINIMIZE) del expr1 del expr2 #载入子问题的约束 #子问题约束1 expr = 0 for j in demand: expr = x1[j] + expr sub_problem1.addConstr(expr <= s) del expr #子问题约束2, for i in plants: for j in demand: if round(a[i, j]) == 1: sub_problem1.addConstr(y1[i] >= x1[j]) #解子问题 sub_problem1.optimize() #申明big set的子问题----sub_problem2 ----------- #big set #big set #big set sub_problem2 = grb.Model('sub_problem2') sub_problem2.setParam('OutputFlag', 0) #申明子问题的变量 x2 = sub_problem2.addVars(demand, vtype=grb.GRB.BINARY, name='x2') y2 = sub_problem2.addVars(plants, vtype=grb.GRB.BINARY, name='y2') #设置目标函数 expr1 = 0 expr2 = 0 for i in plants: expr1 = expr1 + (1 - y2[i]) * I[i].x for j in demand: expr2 = expr2 + lower_demand[j] * (1 - x2[j]) sub_problem2.setObjective(expr2 - expr1, grb.GRB.MINIMIZE) del expr1 del expr2 #载入子问题的约束 #子问题约束1 expr = 0 for j in demand: expr = x2[j] + expr sub_problem2.addConstr(expr >= S) del expr #子问题约束2, for i in plants: for j in demand: if round(a[i, j]) == 1: sub_problem2.addConstr(y2[i] >= x2[j]) #解子问题 sub_problem2.optimize() ''' 2个和weight 有关的子问题 ''' #申明small set的子问题----sub_problem1 sub_problem3 = grb.Model('sub_problem3') sub_problem3.setParam('OutputFlag', 0) #申明子问题的变量 x3 = sub_problem3.addVars(demand, vtype=grb.GRB.BINARY, name='x3') y3 = sub_problem3.addVars(plants, vtype=grb.GRB.BINARY, name='y3') #设置目标函数 expr1 = 0 expr2 = 0 for i in plants: expr1 = expr1 + y3[i] * I[i].x for j in demand: expr2 = expr2 + upper_demand[j] * x3[j] sub_problem3.setObjective(expr1 - expr2, grb.GRB.MINIMIZE) del expr1 del expr2 #载入子问题的约束 #子问题约束1 sub_problem3.addConstr( grb.quicksum(x3[j] * upper_demand[j] for j in demand) <= weight * M) #子问题约束2, for i in plants: for j in demand: if round(a[i, j]) == 1: sub_problem3.addConstr(y3[i] >= x3[j]) #解子问题 sub_problem3.optimize() #申明big weight的子问题----sub_problem2 ----------- #big set #big set #big set sub_problem4 = grb.Model('sub_problem4') sub_problem4.setParam('OutputFlag', 0) #申明子问题的变量 x4 = sub_problem4.addVars(demand, vtype=grb.GRB.BINARY, name='x4') y4 = sub_problem4.addVars(plants, vtype=grb.GRB.BINARY, name='y4') #设置目标函数 expr1 = 0 expr2 = 0 for i in plants: expr1 = expr1 + (1 - y4[i]) * I[i].x for j in demand: expr2 = expr2 + lower_demand[j] * (1 - x4[j]) sub_problem4.setObjective(expr2 - expr1, grb.GRB.MINIMIZE) del expr1 del expr2 #载入子问题的约束 #子问题约束1 sub_problem4.addConstr( grb.quicksum(x4[j] * lower_demand[j] for j in demand) >= (1 - weight) * M) #子问题约束2, for i in plants: for j in demand: if round(a[i, j]) == 1: sub_problem4.addConstr(y4[i] >= x4[j]) #解子问题 sub_problem4.optimize() #判断子问题的目标函数值是否为非负数,若是,则主问题得到了最优解,break;否则加入新的约束到主问题中 if sub_problem1.ObjVal >= 0 and sub_problem2.ObjVal >= 0 and sub_problem3.ObjVal >= 0 and sub_problem4.ObjVal >= 0: break else: if sub_problem1.ObjVal < -0.0001: print('small_set:', sub_problem1.ObjVal) expr1 = 0 expr2 = 0 a_temp = [0] * num_plants for j in demand: a_temp = x1[j].x * a[:, j] + a_temp expr2 = upper_demand[j] * x1[j].x + expr2 for i in plants: if round(a_temp[i]) != 0: expr1 = expr1 + round(a_temp[i]) / round( a_temp[i]) * I[i] temp_expr = expr1 >= expr2 master_problem.addConstr(temp_expr) #加新的约束到主问题中 del expr1 del expr2 del temp_expr del a_temp add_constraints_time += 1 if sub_problem2.ObjVal < -0.0001: print('big_set:', sub_problem2.ObjVal) expr1 = 0 expr2 = 0 a_temp = [0] * num_plants for j in demand: a_temp = x2[j].x * a[:, j] + a_temp expr2 = lower_demand[j] * ( int(not x2[j].x)) + expr2 for i in plants: expr1 = expr1 + int(not a_temp[i]) * I[i] temp_expr = expr1 <= expr2 master_problem.addConstr(temp_expr) #加新的约束到主问题中 del expr1 del expr2 del temp_expr del a_temp add_constraints_time += 1 if sub_problem3.ObjVal < -0.0001: print('small_set:', sub_problem3.ObjVal) expr1 = 0 expr2 = 0 a_temp = [0] * num_plants for j in demand: a_temp = x3[j].x * a[:, j] + a_temp expr2 = upper_demand[j] * x3[j].x + expr2 for i in plants: if round(a_temp[i]) != 0: expr1 = expr1 + round(a_temp[i]) / round( a_temp[i]) * I[i] temp_expr = expr1 >= expr2 master_problem.addConstr(temp_expr) #加新的约束到主问题中 del expr1 del expr2 del temp_expr del a_temp add_constraints_time += 1 if sub_problem4.ObjVal < -0.0001: print('big_set:', sub_problem4.ObjVal) expr1 = 0 expr2 = 0 a_temp = [0] * num_plants for j in demand: a_temp = x4[j].x * a[:, j] + a_temp expr2 = lower_demand[j] * ( int(not x4[j].x)) + expr2 for i in plants: expr1 = expr1 + int(not a_temp[i]) * I[i] temp_expr = expr1 <= expr2 master_problem.addConstr(temp_expr) #加新的约束到主问题中 del expr1 del expr2 del temp_expr del a_temp add_constraints_time += 1 time_end = time.clock() if master_problem.status == 2: I_return = [] Z_return = [] p = 0 open_DC = 0 for i in plants: open_DC = open_DC + Z[i].x p = p + I[i].x I_return.append(I[i].x) Z_return.append(Z[i].x) return master_problem, constraintType, iterValue, [ s, open_DC, I_return, Z_return, p, p / TI, master_problem.ObjVal, time_end - time_start, add_constraints_time, 'optimal' ] elif master_problem.status == 3: return master_problem, constraintType, iterValue, [ '-', '-', '-', '-', '-', '-', '-', '-', '-', 'infeasible' ]