class UraniumMineModel: """ This class represents the model for the uranium mine problem. """ 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) # Alternatively #self.m.addConstrs(self.x[a] - self.x[b] <= 0 for a, b in p.precedences) def solve(self): self.m.optimize() def printSolution(self): print("Total profit ", self.m.ObjVal) for b in self.p.blocks: print("%s %g"%(self.x[b].varName,self.x[b].x))
class CuttingStockModel2: 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.INTEGER, 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 solve(self): self.m.optimize() def print_solution(self): print("Objective ", self.m.objVal) for v in self.m.getVars(): print("%s %g" % (v.varName, v.x))
class CuttingStockModel1: 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)],vtype=GRB.BINARY,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.INTEGER,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 solve(self): self.m.optimize() def print_solution(self): print("Objective ", self.m.objVal) for v in self.m.getVars(): print("%s %g" % (v.varName, v.x))
class FullModel: def __init__(self, fsp: FacilitySizingProblem): self.fsp = fsp self.m = Model() # Creates the variables self.y = self.m.addVars(fsp.n_facilities, fsp.n_customers, name="y") self.x = self.m.addVars(fsp.n_facilities, name="x") # Creates the objective expr = 0 for i in range(fsp.n_facilities): expr += fsp.fixed_costs[i] * self.x[i] for j in range(fsp.n_customers): expr += fsp.delivery_costs[i][j] * self.y[i, j] self.m.setObjective(expr, GRB.MINIMIZE) # Constraints for i in range(fsp.n_facilities): self.m.addConstr(self.y.sum(i, '*') <= self.x[i]) for j in range(fsp.n_customers): self.m.addConstr(self.y.sum('*', j) >= fsp.demands[j]) self.m.addConstrs(self.x[i] <= self.fsp.capacity[i] for i in range(fsp.n_facilities)) def solve(self): self.m.optimize() def print_solution(self): for i in range(self.fsp.n_facilities): print('%s %g' % (self.x[i].varName, self.x[i].x)) print('Obj: %g' % self.m.objVal)
class Master: 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)) def solve(self): self.m.optimize() def get_solution(self): return [self.x[i].x for i in range(self.fsp.n_facilities)], self.phi.x 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 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 print_solution(self): for i in range(self.fsp.n_facilities): print('%s %g' % (self.x[i].varName, self.x[i].x)) print('Obj: %g' % self.m.objVal)
class PPFullModel(): """ Class representing the full model for the procurement problem. """ def __init__(self, pp: ProcurementProblem): self.m = Model() self.pp = pp # Creates the variables self.x = self.m.addVars(self.pp.n_materials, name="x") # Creates the objective # The expression is obtained by multiplying x to the costs dictionary. # See the Gurobi docs for tupledic product here # https://www.gurobi.com/documentation/8.1/refman/py_tupledict_prod.html expr = self.x.prod(self.pp.costs) self.m.setObjective(expr, GRB.MINIMIZE) # Creates the constraints self.m.addConstrs((self.x[i] <= self.pp.max_production[i] for i in range(self.pp.n_materials)), name='max_p') self.m.addConstrs((self.x[i] >= self.pp.min_production[i] for i in range(self.pp.n_materials)), name='min_p') self.m.addConstr(self.x.prod(self.pp.consumption) >= self.pp.demand) def solve(self): """ Solves the problem. :return: """ self.m.optimize() def print_solution(self): """ Prints the solution to the problem. :return: """ for i in range(self.pp.n_materials): print('%s %g' % (self.x[i].varName, self.x[i].x)) print('Obj: %g' % self.m.objVal)
class StadiumConstructionModel: """ This class represents the model for the Stadium Construction problem. """ def __init__(self, p: StadiumConstructionProblem): self.p = p self.m = Model('stadium') # Decision variables self.x = self.m.addVars(self.p.tasks, name="x") self.q = self.m.addVar(name="maxtime") # Objective function self.m.setObjective(self.q, sense=GRB.MINIMIZE) # Constraints self.m.addConstrs(self.q - self.x[t] >= 0 for t in p.tasks) self.m.addConstrs(self.x[t1] - self.x[t2] >= p.durations[t1] for (t1, t2) in p.precedences) self.m.addConstrs(self.x[t] >= p.durations[t] for t in p.tasks) def solve(self): self.m.optimize() def printSolution(self): print("Completion time ", self.m.ObjVal) for t in self.p.tasks: print("%s %g" % (self.x[t].varName, self.x[t].x))
def __Simulate(self, d_r): # define the model model = Model('evaluation_problem') model.setParam('OutputFlag', 0) model.modelSense = GRB.MINIMIZE # decision variables X = model.addVars(tuplelist(self.roads_Z), vtype=GRB.CONTINUOUS, lb=0.0, name='X') # objective function objFunc_penal = sum(d_r) - X.sum() model.setObjective(objFunc_penal) # constraints model.addConstrs(X.sum('*', j) <= d_r[j] for j in range(self.n)) model.addConstrs(X.sum(i, '*') <= self.I[i] for i in range(self.m)) # solve model.optimize() # record return {'d_r': d_r, 'X': {f'{r}': X[r].X for r in self.roads_Z}}
class OSP: def __init__(self, fsp: FacilitySizingProblem, x: list): self.fsp = fsp self.m = Model() # Creates the variables y = self.m.addVars(fsp.n_facilities, fsp.n_customers, name="y") # Creates the objective expr = 0 for i in range(fsp.n_facilities): for j in range(fsp.n_customers): expr += fsp.delivery_costs[i][j] * y[i, j] self.m.setObjective(expr, GRB.MINIMIZE) # Constraints self.capacity_constr = self.m.addConstrs( y.sum(i, '*') <= x[i] for i in range(self.fsp.n_facilities)) self.demand_constr = self.m.addConstrs( y.sum('*', j) >= fsp.demands[j] for j in range(fsp.n_customers)) def solve(self): self.m.optimize() def getResults(self): ''' Returns, in this order, 1) the objective value, 2) the vector of optimal duals for the capacity constraints 3) the vector of optimal duals for the demand constraints :return: ''' print(self.capacity_constr) dualsCC = self.m.getAttr(GRB.Attr.Pi, self.capacity_constr) dualsDC = self.m.getAttr(GRB.Attr.Pi, self.demand_constr) return self.m.objVal, dualsCC, dualsDC
class FSP: def __init__(self, fsp: FacilitySizingProblem, x: list): self.fsp = fsp self.m = Model() # Creates the variables y = self.m.addVars(fsp.n_facilities, fsp.n_customers, name="y") v1 = self.m.addVars(fsp.n_facilities, name="v+") v2 = self.m.addVars(fsp.n_customers, name="v-") # Creates the objective expr = v1.sum() + v2.sum() self.m.setObjective(expr, GRB.MINIMIZE) # Constraints self.demand_c = self.m.addConstrs( y.sum('*', j) + v1[j] >= fsp.demands[j] for j in range(fsp.n_customers)) self.capacity_c = self.m.addConstrs( y.sum(i, '*') - v2[i] <= x[i] for i in range(fsp.n_facilities)) def solve(self): self.m.optimize() def getResults(self): ''' Returns, in this order, 1) the objective value, 2) the vector of optimal duals for the capacity constraints 3) the vector of optimal duals for the demand constraints :return: ''' dualsCC = [self.capacity_c[i].Pi for i in range(self.fsp.n_facilities)] dualsDC = [self.demand_c[j].Pi for j in range(self.fsp.n_customers)] return self.m.objVal, dualsCC, dualsDC
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
class AlloyProductionModel: """ This class represents the mathematical model for the Alloy Production Problem. """ 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 solve(self): self.m.optimize() def print_solution(self): print("Objective ", self.m.ObjVal) for m in self.materials: print("%s %g " % (self.x[m].varName, self.x[m].x))
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 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