def __init__(self, p: AlloyProductionProblem): self.p = p self.m = Model('APP') # Creates the decision variables self.materials = list(p.availability.keys()) chemicals = list(p.max_grade.keys()) self.x = self.m.addVars(self.materials, name='x') # Creates the objective function expr = self.x.prod(p.cost) self.m.setObjective(expr, sense=GRB.MINIMIZE) # Creates the constraints # Min content self.m.addConstrs( quicksum([p.content[(k, m)] * self.x[m] for m in self.materials]) >= p.min_grade[k] * self.x.sum('*') for k in chemicals) # Max content self.m.addConstrs( quicksum([p.content[(k, m)] * self.x[m] for m in self.materials]) <= p.max_grade[k] * self.x.sum('*') for k in chemicals) # Availability self.m.addConstrs(self.x[m] <= p.availability[m] for m in self.materials) # Demand self.m.addConstr(self.x.sum('*') >= p.demand)
def __SBM_super_C(self): for k in self.DMUs: MODEL = gurobipy.Model() fi = MODEL.addVars(self.m1) lambdas = MODEL.addVars(self.DMUs) fo = MODEL.addVars(self.m2) t = MODEL.addVar() MODEL.update() MODEL.setObjective( t + t / self.m1 * quicksum(fi[j] for j in range(self.m1)), sense=gurobipy.GRB.MINIMIZE) MODEL.addConstrs( quicksum(lambdas[i] * self.X[i][j] for i in self.DMUs if i != k) <= (1 + fi[j]) * self.X[k][j] for j in range(self.m1)) MODEL.addConstrs( quicksum(lambdas[i] * self.Y[i][j] for i in self.DMUs if i != k) >= (1 - fo[j]) * self.Y[k][j] for j in range(self.m2)) MODEL.addConstr( t - t / self.m2 * quicksum(fo[j] for j in range(self.m2)) == 1) MODEL.setParam('OutputFlag', 0) MODEL.setParam("NonConvex", 2) MODEL.optimize() self.Result.at[k, ('效益分析', '效率')] = MODEL.objVal return self.Result
def addOptimalityCut(masterProblem, subProblem, A, b, n): # get dual value dualValue = subProblem.Pi #add optimality cut \ita optimalitycut = ITA[n + 1] - grb.quicksum( dualValue[i] * (b[n][i] - grb.quicksum(A[i][j] * X[j + 1] for j in range(A.shape[1]))) for i in range(A.shape[0])) >= 0 masterProblem.addConstr(optimalitycut)
def addFeasibilityCut(masterProblem, subProblem, A, b, n): # find the extreme ray # !!! FarkasDual gets the reverse-directional extreme ray extremeRay = -np.asarray(subProblem.FarkasDual) #add feasiblity cut: r^j(b-Ax) <= 0 feasibilitycut = grb.quicksum( extremeRay[i] * (b[n][i] - grb.quicksum(A[i][j] * X[j + 1] for j in range(A.shape[1]))) for i in range(A.shape[0])) <= 0 masterProblem.addConstr(feasibilitycut)
def __init__(self,p:KnapsackProblem): self.p = p self.m = Model('knapsack') # Creates the decision variables self.x = self.m.addVars(len(p.rewards),vtype = GRB.BINARY,name = "x") # Creates the objective self.m.setObjective(quicksum([self.p.rewards[i] * self.x[i] for i in range(len(self.p.rewards))]),sense=GRB.MAXIMIZE) # Creates the constraint self.m.addConstr(quicksum([self.p.weights[i] * self.x[i] for i in range(len(self.p.weights))]) <= self.p.capacity)
def solve_restricted_primal(self, demands, demands_next, p): self.obj = 0. m = Model("multi-unit-auction") # self.m.params.LogToConsole = 0 self.allocation_vars = dict() for agent in self.agents: for i in range(1, self.supply + 1): self.allocation_vars[agent.id, i] = m.addVar(lb=0., ub=1., vtype=GRB.CONTINUOUS, name='x_%s_%s' % (agent.id, i)) m.update() for agent in self.agents: if len(demands[agent.id]) > 0 and len(demands_next[agent.id]) > 0: m.addConstr(quicksum(self.allocation_vars[agent.id, i] for i in range(1, self.supply + 1)), GRB.EQUAL, 1, name="u_%s_strict" % agent.id) else: m.addConstr(quicksum(self.allocation_vars[agent.id, i] for i in range(1, self.supply + 1)), GRB.LESS_EQUAL, 1, name="u_%s" % agent.id) for j in range(1, self.supply + 1): if j not in [demand.quantity for demand in demands[agent.id]]: m.addConstr(self.allocation_vars[agent.id, j], GRB.EQUAL, 0, name='x_%s_%s_undemanded' % (agent.id, j)) if p > 0: m.addConstr( quicksum(self.allocation_vars[agent.id, i] * i for i in range(1, self.supply + 1) for agent in self.agents), GRB.EQUAL, self.supply, name="price_strict") else: m.addConstr( quicksum(self.allocation_vars[agent.id, i] * i for i in range(1, self.supply + 1) for agent in self.agents), GRB.LESS_EQUAL, self.supply, name="price") obj_expr = LinExpr() for agent in self.agents: for valuation in agent.valuations: obj_expr.addTerms(valuation.quantity, self.allocation_vars[agent.id, valuation.quantity]) m.setObjective(obj_expr, GRB.MAXIMIZE) m.update() m.optimize() m.write('optimal-lp.lp') if m.status == GRB.OPTIMAL: m.write('optimal-lp.sol') for v in [v for v in m.getVars() if v.x != 0.]: print('%s %g' % (v.varName, v.x)) print '' print 'CONSTRAINTS:' for l in m.getConstrs(): if l.Pi > 0: print('%s %g' % (l.constrName, l.Pi)) print m.getObjective().getValue() return m
def __init__(self, p: CuttingStockProblem): self.p = p self.m = Model('CS1') # Decision variables n_large_rolls = self.p.get_max_number_of_large_rolls() n_small_roll_types = len(self.p.demand) print(n_large_rolls, n_small_roll_types) y = self.m.addVars([i for i in range(n_large_rolls)], lb=0, ub=1, vtype=GRB.CONTINUOUS, name="y") z = self.m.addVars([j for j in range(n_small_roll_types)], [i for i in range(n_large_rolls)], lb=0, ub=GRB.INFINITY, vtype=GRB.CONTINUOUS, name="x") # Objective function self.m.setObjective(y.sum('*')) # Constraints # Note that the argument passed to quicksum is a list, and the list is built using comprehension self.m.addConstrs( quicksum([ self.p.width_small_rolls[i] * z[i, j] for i in range(n_small_roll_types) ]) <= self.p.width_large_rolls * y[j] for j in range(n_large_rolls)) self.m.addConstrs( z.sum(i, '*') >= self.p.demand[i] for i in range(n_small_roll_types))
def add_optimality_cut(self, dualsCC: list, dualsDC: list): self.m.addConstr(self.phi - quicksum( [dualsCC[i] * self.x[i] for i in range(self.fsp.n_facilities)]) >= sum([ dualsDC[j] * self.fsp.demands[j] for j in range(self.fsp.n_customers) ])) print("Added optimality cut")
def add_feasibility_cut(self, dualsCC: list, dualsDC: list): self.m.addConstr( quicksum( [dualsCC[i] * self.x[i] for i in range(self.fsp.n_facilities)]) <= -sum([ dualsDC[j] * self.fsp.demands[j] for j in range(self.fsp.n_customers) ])) print("Added feasibility cut")
def SolveStoModel(self) -> Model: StoModel = Model('StoModel') StoModel.setParam('OutputFlag', 0) StoModel.modelSense = GRB.MINIMIZE m, n = self.m, self.n h, f = self.h, self.f d_rs = self.d_rs d_rs_length = len(d_rs) I = StoModel.addVars(m, vtype=GRB.CONTINUOUS, name='I') Z = StoModel.addVars(m, vtype=GRB.BINARY, name='Z') Transshipment_X = StoModel.addVars(self.roads, d_rs_length, vtype=GRB.CONTINUOUS, name='Transshipment_X') objFunc_holding = quicksum(I[i] * h[i] for i in range(m)) objFunc_fixed = quicksum(Z[i] * f[i] for i in range(m)) objFunc_penalty = quicksum(d_r[j] - Transshipment_X.sum('*', j, k) for k, d_r in d_rs.items() for j in range(n)) objFunc = objFunc_holding + objFunc_fixed + (objFunc_penalty / d_rs_length) StoModel.setObjective(objFunc) # 约束1 for k in range(d_rs_length): StoModel.addConstrs( Transshipment_X.sum(i, '*', k) <= I[i] for i in range(m)) # 约束2 for k, d_r in d_rs.items(): StoModel.addConstrs( Transshipment_X.sum('*', j, k) <= d_r[j] for j in range(n)) # 约束3 I_i<=M*Z_i StoModel.addConstrs(I[i] <= 20000 * Z[i] for i in range(m)) # 求解评估模型 StoModel.optimize() self.model = StoModel return StoModel
def __init__(self,p: UraniumMineProblem): self.p = p self.m = Model('uranium') # Decision variables self.x = self.m.addVars(self.p.blocks,vtype=GRB.BINARY,name="x") # Objective function expr = quicksum([(p.values[b] - p.costs[b]) * self.x[b] for b in p.blocks]) self.m.setObjective(expr,sense=GRB.MAXIMIZE) # Constraints self.m.addConstrs(self.x[a] - self.x[b] <= 0 for (a,b) in p.precedences)
def _balancing(self, flow_graph, sinks, frontier, demands): configure_gurobi() model = Model() xij = {i: {} for i in frontier} for node in frontier: congestion = sum(flow_graph[node][neighbor] for neighbor in flow_graph[node]) for neighbor in flow_graph[node]: assert neighbor in sinks xij[node][neighbor] = model.addVar(vtype=GRB.CONTINUOUS, name=f"x_{node}_{neighbor}") model.addConstr(xij[node][neighbor] >= 0) model.addConstr(quicksum(xij[node][neighbor] for neighbor in flow_graph[node]) == congestion) sink_predecessors = {i: [] for i in sinks} for node in frontier: for neighbor in flow_graph[node]: sink_predecessors[neighbor].append(node) bj = {} for node in sinks: bj[node] = model.addVar(vtype=GRB.CONTINUOUS, name=f"b_{node}") model.addConstr(bj[node] == quicksum(xij[pred][node] for pred in sink_predecessors[node]) + demands[node]) model.setObjective(quicksum(bj[node] * bj[node] for node in sinks), GRB.MINIMIZE) model.optimize() any_edge_deleted = False for node in frontier: to_delete = [] for neighbor in flow_graph[node]: flow = xij[node][neighbor].X if flow < EPS: to_delete.append(neighbor) any_edge_deleted = True else: flow_graph[node][neighbor] = flow for neighbor in to_delete: del flow_graph[node][neighbor] return any_edge_deleted
def SolveDetModel(self) -> Model: DetModel = Model('StoModel') DetModel.setParam('OutputFlag', 0) DetModel.modelSense = GRB.MINIMIZE m, n = self.m, self.n h, f = self.h, self.f mu = self.det_param['mu'] I = DetModel.addVars(m, vtype=GRB.CONTINUOUS, name='I') Z = DetModel.addVars(m, vtype=GRB.BINARY, name='Z') Transshipment_X = DetModel.addVars(self.roads, vtype=GRB.CONTINUOUS, name='Transshipment_X') objFunc_holding = quicksum(I[i] * h[i] for i in range(m)) objFunc_fixed = quicksum(Z[i] * f[i] for i in range(m)) objFunc_penalty = quicksum(mu[j] - Transshipment_X.sum('*', j) for j in range(n)) objFunc = objFunc_holding + objFunc_fixed + objFunc_penalty DetModel.setObjective(objFunc) # 约束1 DetModel.addConstrs( Transshipment_X.sum(i, '*') <= I[i] for i in range(m)) # 约束2 DetModel.addConstrs( Transshipment_X.sum('*', j) <= mu[j] for j in range(n)) # 约束3 I_i<=M*Z_i DetModel.addConstrs(I[i] <= 20000 * Z[i] for i in range(m)) # 求解评估模型 DetModel.optimize() self.model = DetModel return DetModel
def __init__(self, p:CuttingStockProblem): self.p = p self.m = Model('CS1') # Decision variables n_patterns = len(self.p.get_feasible_patterns()) x = self.m.addVars(n_patterns,lb= 0, ub= GRB.INFINITY, vtype=GRB.CONTINUOUS,name="x") # Objective function self.m.setObjective(x.sum('*')) # Constraints # Note that the argument passed to quicksum is a list, and the list is built using comprehension self.m.addConstrs(quicksum([self.p.get_feasible_patterns()[q][i] * x[q] for q in range(n_patterns)]) >= self.p.demand[i] for i in range(len(p.demand)))
def __init__(self, fsp: FacilitySizingProblem): self.fsp = fsp self.m = Model() # Creates the variables self.x = self.m.addVars(fsp.n_facilities, vtype=GRB.CONTINUOUS, name="x") self.phi = self.m.addVar(name="phi") # Creates the objective expr = self.phi + quicksum([ self.fsp.fixed_costs[i] * self.x[i] for i in range(self.fsp.n_facilities) ]) self.m.setObjective(expr, GRB.MINIMIZE) # Creates the constraints self.m.addConstrs(self.x[i] <= self.fsp.capacity[i] for i in range(fsp.n_facilities))
subProblem.setParam('OutputFlag', 0) subProblem.setParam( 'InfUnbdInfo', 1 ) #InfUnbdInfo is the prerequire for getting FarkasProof attribute # variables Y = subProblem.addVars([1, 2], vtype=grb.GRB.CONTINUOUS, lb=[0, 0], obj=[15, 12], name='Y') # add second-stage recourse constraints subProblem.addConstrs( grb.quicksum(G[i][j] * Y[j + 1] for j in range(G.shape[1])) >= b[n][i] - grb.quicksum(A[i][j] * X[j + 1].x for j in range(A.shape[1])) for i in range(G.shape[0])) # --- 2.1. solve the k-th subproblem subProblem.optimize() # --- 2.1.1. subproblem is infeasible, then add a feasibility cut (should find out the extreme rays) if subProblem.Status == grb.GRB.INFEASIBLE: addFeasibilityCut(masterProblem, subProblem, A, b, n) ADDFEASIBILITYCUT_NUM += 1 # --- 2.1.2. add optimality cut or get optimal solution elif subProblem.Status == grb.GRB.OPTIMAL: # if subproblem == ita, we now get optimal solution in the master problem
def _optimize( families: Iterable[Family], days: Iterable[Day], family_index: Mapping[FamilyID, Family], mip_start: Optional[Assignments], ) -> Solution: with gurobi.model("santa-19") as model: assignment_vars = model.addVars( tuplelist((family.id, family_choice) for family in families for family_choice in family.choices), name="x", vtype=GRB.BINARY, ) occupancy_vars = model.addVars( tuplelist((occupancy, day) for day in days for occupancy in _FEASIBLE_OCCUPANCIES), name="delta", vtype=GRB.BINARY, ) occupancy_pairs = {(o, o_p, d): accounting_cost(o, o_p) for o in _FEASIBLE_OCCUPANCIES for o_p in _FEASIBLE_OCCUPANCIES for d in days} occupancy_pair_vars = model.addVars(occupancy_pairs.keys(), name="phi", lb=0, ub=1) logger.info("Created variables") model.addConstrs( (quicksum(assignment_vars[(family_id, family_choice)] for family_choice in family_index[family_id].choices) == 1 for family_id in family_index.keys()), name="assg", ) model.addConstrs((occupancy_vars.sum("*", day) == 1 for day in days), name="occ_c") model.addConstrs( (quicksum( assignment_vars.get((family.id, day), 0) * family.number_of_members for family in families) == quicksum( occupancy_vars[(occupancy, day)] * occupancy for occupancy in _FEASIBLE_OCCUPANCIES) for day in days), name="occ", ) n_days = len(list(days)) model.addConstrs( (occupancy_pair_vars.sum(occupancy, "*", d) == occupancy_vars[(occupancy, d)] for occupancy in _FEASIBLE_OCCUPANCIES for d in days), name="occ_l_1", ) model.addConstrs( (occupancy_pair_vars.sum("*", occupancy, d + 1) == occupancy_vars[(occupancy, d + 1)] for occupancy in _FEASIBLE_OCCUPANCIES for d in days if d + 1 < n_days), name="occ_l_2", ) logger.info("Set constraints") pref_cost_expr = quicksum( assignment_vars[(family.id, family_choice)] * preference_cost( family_choice, family.choice_index, family.number_of_members) for family in families for family_choice in family.choices) accounting_cost_expr = quicksum( occupancy_vars.sum(pair[0], pair[1], "*") * cost for pair, cost in occupancy_pairs.items()) model.setObjective(pref_cost_expr + accounting_cost_expr, sense=GRB.MINIMIZE) logger.info("Set objective") if mip_start: for family_id, assigned_day in mip_start.items(): v = assignment_vars.get((family_id, assigned_day), None) if v: v.start = 1 model.optimize() if model.status == GRB.INFEASIBLE: model.computeIIS() model.write("conflict.lp") raise Exception("Infeasible model.") else: assignments = { k[0]: k[1] for k, v in assignment_vars.items() if v.X > 0.5 } model.write("sol.sol") return Solution.from_assignments(assignments, days, family_index)
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 Build_LDR_Model(self): """ LDR for location-inventpry problem is only feasible when all affine coefficients equal to 0, which violates from what we want. For more info about how to design a reasonable prepositioning network, see: http://web.hec.ca/pages/erick.delage/LRC_TRO.pdf The above paper assume support set is a convex polyhedron characterized by linear constraints. """ m, n = self.m, self.n f, h = self.f, self.h mu, sigma = self.mu, self.sigma roads = self.roads INF = float('inf') f_ks, K = self.ldr_params['f_k'], len(self.ldr_params['f_k']) # declare model ldr_model = Model() # decision variables I = ldr_model.addVars(m, vtype=GRB.CONTINUOUS, lb=0.0, name='I') Z = ldr_model.addVars(m, vtype=GRB.BINARY, lb=0.0, name='Z') t = ldr_model.addVars(n, vtype=GRB.CONTINUOUS, lb=-INF, name='t') gamma = ldr_model.addVar(lb=-INF, vtype=GRB.CONTINUOUS, name='gamma') s = ldr_model.addVars(K, vtype=GRB.CONTINUOUS, lb=0.0, name='s') phi = ldr_model.addVars(K, vtype=GRB.CONTINUOUS, lb=0.0, name='phi') psi = ldr_model.addVars(K, vtype=GRB.CONTINUOUS, lb=-INF, name='psi') xi = ldr_model.addVars(K, vtype=GRB.CONTINUOUS, lb=-INF, name='xi') eta = ldr_model.addVars(n, K, vtype=GRB.CONTINUOUS, lb=0.0, name='eta') tau = ldr_model.addVars(n, K, vtype=GRB.CONTINUOUS, lb=-INF, name='tau') theta = ldr_model.addVars(n, K, vtype=GRB.CONTINUOUS, lb=-INF, name='theta') w = ldr_model.addVars(m, K, vtype=GRB.CONTINUOUS, lb=0.0, name='w') lambd = ldr_model.addVars(m, K, vtype=GRB.CONTINUOUS, lb=-INF, name='lambda') delta = ldr_model.addVars(m, K, vtype=GRB.CONTINUOUS, lb=-INF, name='delta') alpha_0 = ldr_model.addVars(roads, vtype=GRB.CONTINUOUS, lb=-INF, name='alpha_0') alpha = ldr_model.addVars(roads, n, vtype=GRB.CONTINUOUS, lb=-INF, name='alpha') beta = ldr_model.addVars(roads, K, vtype=GRB.CONTINUOUS, lb=-INF, name='beta') # objective function obj1 = quicksum([f[i]*Z[i] for i in range(m)]) obj2 = quicksum([h[i]*I[i] for i in range(m)]) obj3 = quicksum([mu[i]*t[i] for i in range(m)]) obj4 = quicksum(s[k]*matmul(matmul(f_k, sigma), f_k) for k, f_k in enumerate(f_ks)) obj5 = gamma ldr_model.setObjective(obj1 + obj2 + obj3 + obj4 + obj5) ldr_model.modelSense = GRB.MINIMIZE # constraint # c1 ldr_model.addConstr(gamma + alpha_0.sum() >= 1/2*(phi.sum() - psi.sum()), name='c1') # c2 ldr_model.addConstrs((1/2*(phi[k]+psi[k]) == beta.sum('*', '*', k) + s[k]*len(roads) for k in range(K)), name='c2') # c3 a_star_star = [alpha.sum('*', '*', l) for l in range(n)] ldr_model.addConstrs((xi[k]*f_ks[k][l] <= t[l]+a_star_star[l]-1 for k in range(K) for l in range(n)), name='c3') # c4 ldr_model.addConstrs((-alpha_0.sum('*', j) >= 1/2*(eta.sum(j, '*')-tau.sum(j, '*')) for j in range(n)), name='c4') # c5 ldr_model.addConstrs((-1/2*(eta[j, k]+tau[j, k]) == beta.sum('*', j, k) for k in range(K) for j in range(n)), name='c5') # c6 for j in range(n): a_star_j = [alpha.sum('*', j, l) if l != j else alpha.sum('*', j, l)-1 for l in range(n)] for k, f_k in enumerate(f_ks): ldr_model.addConstrs(-theta[j, k]*f_k[l] >= a_star_j[l] for l in range(n)) # c7 ldr_model.addConstrs((I[i]-alpha_0.sum(i, '*') >= 1/2*(w.sum(i, '*')-lambd.sum(i, '*')) for i in range(m)), name='c7') # c8 ldr_model.addConstrs((-1/2*(w[i, k]+lambd[i, k]) == beta.sum(i, '*', k) for i in range(m) for k in range(K)), name='c8') # c9 for i in range(m): a_i_star = [alpha.sum(i, '*', l) for l in range(n)] for k, f_k in enumerate(f_ks): ldr_model.addConstrs(-delta[i, k]*f_k[l] >= a_i_star[l] for l in range(n)) # c10 I,Z ldr_model.addConstrs(I[i] <= 10000*Z[i] for i in range(m)) # c11 ldr_model.addConstrs(phi[k]*phi[k] >= psi[k]*psi[k] + xi[k]*xi[k] for k in range(K)) ldr_model.addConstrs(eta[i, k]*eta[i, k] >= tau[i, k]*tau[i, k] + theta[i, k]*theta[i, k] for k in range(K) for i in range(m)) ldr_model.addConstrs(w[i, k]*w[i, k] >= lambd[i, k]*lambd[i, k] + delta[i, k]*delta[i, k] for k in range(K) for i in range(m)) # update ldr_model.update() ldr_model.optimize() # print(I) # print(Z) # print(alpha_0) # print(alpha) # print(beta) # print(ldr_model.ObjVal) self.model = ldr_model
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)
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 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
def __init__(self, supply, agents, gap, restriced=False): print '' print 'Optimal Solver:' self.m = Model("multi-unit-auction") self.m.params.LogToConsole = 0 self.allocation_vars = dict() for agent in agents: for i in range(1, supply + 1): self.allocation_vars[agent.id, i] = self.m.addVar(lb=0., ub=1., vtype=GRB.CONTINUOUS, name='x_%s_%s' % (agent.id, i)) self.m.update() for agent in agents: self.m.addConstr(quicksum(self.allocation_vars[agent.id, i] for i in range(1, supply + 1)), GRB.LESS_EQUAL, 1, name="u_%s" % agent.id) if restriced: for valuation in agent.valuations: if valuation.valuation > 0: self.m.addConstr(self.allocation_vars[agent.id, valuation.quantity] >= epsilon, name="not_zero_%s_%s" % (agent.id, valuation.quantity)) self.m.addConstr(quicksum(self.allocation_vars[agent.id, i]*i for i in range(1, supply + 1) for agent in agents), GRB.LESS_EQUAL, supply, name="price") obj_expr = LinExpr() for agent in agents: for valuation in agent.valuations: obj_expr.addTerms(valuation.valuation, self.allocation_vars[agent.id, valuation.quantity]) self.m.setObjective(obj_expr, GRB.MAXIMIZE) self.m.update() self.m.optimize() # # for agent in agents: # for i in range(1, supply + 1): # self.allocation_vars[agent.id, i] = self.m.addVar(vtype=GRB.CONTINUOUS, lb=0, # name='x_%s_%s' % (agent.id, i)) # # self.m.update() # # self.m.addConstr(quicksum(self.allocation_vars[agent.id, i] for i in range(1, supply + 1) for agent in agents), # GRB.LESS_EQUAL, supply / gap, name="price") # for agent in agents: # for i in range(1, supply): # self.m.addConstr(self.allocation_vars[agent.id, i + 1] - self.allocation_vars[agent.id, i], # GRB.LESS_EQUAL, 0, name="chain_%s_%s" % (agent.id, i)) # self.m.addConstr(self.allocation_vars[agent.id, i], GRB.LESS_EQUAL, 1. / gap, # name="p_%s_%s" % (agent.id, i)) # self.m.addConstr(self.allocation_vars[agent.id, supply], GRB.GREATER_EQUAL, 0, name="greater_%s" % agent.id) # self.m.addConstr(self.allocation_vars[agent.id, 1], GRB.LESS_EQUAL, 1. / gap, name="u_%s" % agent.id) # # # m.addConstr(x11 + 2*x12 + 3*x13 + 4*x14 + x21 + 2*x22 + 3*x23 + 4*x24, GRB.LESS_EQUAL, 4, name="p_an") # # obj_expr = LinExpr() # for agent in agents: # prev_val = None # for valuation in agent.valuations: # try: # prev_val = next(val for val in agent.valuations if val.quantity == valuation.quantity - 1) # except StopIteration: # pass # marginal_value = valuation.valuation - (prev_val.valuation if prev_val else 0) # obj_expr.addTerms(marginal_value, self.allocation_vars[agent.id, valuation.quantity]) # self.m.setObjective(obj_expr, GRB.MAXIMIZE) # # self.m.optimize() for v in [v for v in self.m.getVars() if v.x != 0.]: print('%s %g' % (v.varName, v.x)) print '' print 'CONSTRAINTS:' for l in self.m.getConstrs(): if l.Pi > 0: print('%s %g' % (l.constrName, l.Pi)) print self.m.getObjective().getValue() # print 'Optimal solution:' # for v in self.m.getVars(): # print('%s %g' % (v.varName, v.x)) # for l in self.m.getConstrs(): # if l.Pi > 0: # print('%s %g' % (l.constrName, l.Pi)) print 'OPT social welfare %s | %s/%s=%s' % ( self.m.getObjective().getValue(), self.m.getObjective().getValue(), gap, self.m.getObjective().getValue() / gap) self.m.write('optimal-lp.lp') self.m.write('optimal-lp.sol')
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 addCover(self, indices: list, rhs: int): self.m.addConstr( quicksum([self.x[indices[i]] for i in range(len(indices))]) <= rhs)
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' ]
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 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' ]