class Backup(object): """ Class object for normal-based backup network model. Parameters ---------- nodes: set of nodes links: set of links capacity: capacities per link based based on random failures mean: mean for failure random variable std: standard deviation for failure random variable invstd: inverse of Phi-normal distribution for (1-epsilon) Returns ------- solution: set of capacity assigned per backup link. """ # Private model object __model = [] # Private model variables __BackupCapacity = {} __bBackupLink = {} __ValidLink = {} # Private model parameters __links = [] __nodes = [] __capacity = [] __mean = [] __std = [] __invstd = 1 def __init__(self,nodes,links,capacity,mean,std,invstd): ''' Constructor ''' self.__links = links self.__nodes = nodes self.__capacity = capacity self.__mean = mean self.__std = std self.__invstd = invstd self.__loadModel() def __loadModel(self): # Create optimization model self.__model = Model('Backup') # Auxiliary variables for SOCP reformulation U = {} R = {} # Create variables for i,j in self.__links: self.__BackupCapacity[i,j] = self.__model.addVar(lb=0, obj=1, name='Backup_Capacity[%s,%s]' % (i, j)) self.__model.update() for i,j in self.__links: for s,d in self.__links: self.__bBackupLink[i,j,s,d] = self.__model.addVar(vtype=GRB.BINARY,obj=1,name='Backup_Link[%s,%s,%s,%s]' % (i, j, s, d)) self.__model.update() for i,j in self.__links: U[i,j] = self.__model.addVar(obj=1,name='U[%s,%s]' % (i, j)) self.__model.update() for i,j in self.__links: for s,d in self.__links: R[i,j,s,d] = self.__model.addVar(obj=1,name='R[%s,%s,%s,%s]' % (i,j,s,d)) self.__model.update() self.__model.modelSense = GRB.MINIMIZE #m.setObjective(quicksum([fixedCosts[p]*open[p] for p in plants])) self.__model.setObjective(quicksum(self.__BackupCapacity[i,j] for i,j in self.__links)) self.__model.update() #------------------------------------------------------------------------# # Constraints definition # # # # # #------------------------------------------------------------------------# # Link capacity constraints for i,j in self.__links: self.__model.addConstr(self.__BackupCapacity[i,j] >= quicksum(self.__mean[s,d]*self.__bBackupLink[i,j,s,d] for (s,d) in self.__links) + U[i,j]*self.__invstd,'[CONST]Link_Cap_%s_%s' % (i, j)) self.__model.update() # SCOP Reformulation Constraints for i,j in self.__links: self.__model.addConstr(quicksum(R[i,j,s,d]*R[i,j,s,d] for (s,d) in self.__links) <= U[i,j]*U[i,j],'[CONST]SCOP1[%s][%s]' % (i, j)) self.__model.update() # SCOP Reformulation Constraints for i,j in self.__links: for s,d in self.__links: self.__model.addConstr(self.__std[s,d]*self.__bBackupLink[i,j,s,d] == R[i,j,s,d],'[CONST]SCOP2[%s][%s][%s][%s]' % (i, j,s,d)) self.__model.update() for i in self.__nodes: for s,d in self.__links: # Flow conservation constraints if i == s: self.__model.addConstr(quicksum(self.__bBackupLink[i,j,s,d] for i,j in self.__links.select(i,'*')) - quicksum(self.__bBackupLink[j,i,s,d] for j,i in self.__links.select('*',i)) == 1,'Flow1[%s,%s,%s,%s]' % (i,j,s, d)) # Flow conservation constraints elif i == d: self.__model.addConstr(quicksum(self.__bBackupLink[i,j,s,d] for i,j in self.__links.select(i,'*')) - quicksum(self.__bBackupLink[j,i,s,d] for j,i in self.__links.select('*',i)) == -1,'Flow2[%s,%s,%s,%s]' % (i,j,s, d)) # Flow conservation constraints else: self.__model.addConstr(quicksum(self.__bBackupLink[i,j,s,d] for i,j in self.__links.select(i,'*')) - quicksum(self.__bBackupLink[j,i,s,d] for j,i in self.__links.select('*',i)) == 0,'Flow3[%s,%s,%s,%s]' % (i,j,s, d)) self.__model.update() def optimize(self,MipGap, TimeLimit): self.__model.write('backup.lp') if MipGap != None: self.__model.params.timeLimit = TimeLimit if TimeLimit != None: self.__model.params.MIPGap = MipGap # Compute optimal solution self.__model.optimize() # Print solution if self.__model.status == GRB.Status.OPTIMAL: solution = self.__model.getAttr('x', self.__BackupCapacity) for i,j in self.__links: if solution[i,j] > 0: print('%s -> %s: %g' % (i, j, solution[i,j])) else: print('Optimal value not found!\n') solution = [] return solution; def reset(self): ''' Reset model solution ''' self.__model.reset()
def createInstance(self): model = Model() modelVars = {} # x variables are assigned. for i in range(self.m): for j in range(self.n): Vname = 'x_{}_{}'.format(i, j) modelVars[Vname] = model.addVar(vtype=GRB.BINARY, name=Vname) # Term 2: Objective Function obj = quicksum(self.v[j] * modelVars['x_{}_{}'.format(i, j)] for i in range(self.m) for j in range(self.n)) # Term 3: Each job is assigned to at most 1 machine. model.addConstrs( quicksum(modelVars['x_{}_{}'.format(i, j)] for i in range(self.m)) <= 1 for j in range(self.n)) # Term 4: Allows the assignment of at most R resources to a machine. model.addConstrs( quicksum(modelVars['x_{}_{}'.format(i, j)] * self.r[j] for j in self.J[h]) <= self.R for i in range(self.m) for h in range(1, self.k + 1)) # Term 5: Implicit in varaible definition. # Objective Function is set. model._vars = modelVars model.setObjective(obj, GRB.MAXIMIZE) #print(model.getAttr('ModelSense') == GRB.MINIMIZE) return model
def retrieve_values(lp_problem: LpProblem, lp_variables: List[LpVariable], model: gurobipy.Model) -> None: """ Extract the value of variables from the gurobi model and set them into the Flipy objects Parameters ---------- lp_problem: The Flipy object into which the variable values will be set lp_variables: A list of LpVariables of the problem model: The gurobi model to grab the variable values from """ try: var_name_to_values = dict( zip(model.getAttr(gurobipy.GRB.Attr.VarName, model.getVars()), model.getAttr(gurobipy.GRB.Attr.X, model.getVars()))) for var in lp_variables: var.set_value(var_name_to_values[var.name]) for constraint in lp_problem.lp_constraints.values(): if constraint.slack: constraint.slack_variable.set_value( var_name_to_values[constraint.slack_variable.name]) except (gurobipy.GurobiError, AttributeError): pass
def add_constraints(lp_problem: LpProblem, model: gurobipy.Model) -> None: """ Add the constraints in a Flipy LpProblem to a gurobi model Parameters ---------- lp_problem: The Flipy object to grab the constraints from model: The gurobi model to add the constraints to """ for name, constraint in lp_problem.lp_constraints.items(): lhs_expr = [(coef, var.solver_var) for var, coef in constraint.lhs.expr.items()] if constraint.slack: lhs_expr += [((-1 if constraint.sense == 'leq' else 1), constraint.slack_variable.solver_var)] lhs_expr = gurobipy.LinExpr(lhs_expr) lhs_expr.addConstant(constraint.lhs.const) rhs_expr = gurobipy.LinExpr([ (coef, var.solver_var) for var, coef in constraint.rhs.expr.items() ]) rhs_expr.addConstant(constraint.rhs.const) if constraint.sense.lower() == 'leq': relation = gurobipy.GRB.LESS_EQUAL elif constraint.sense.lower() == 'geq': relation = gurobipy.GRB.GREATER_EQUAL else: relation = gurobipy.GRB.EQUAL constraint.solver_constraint = model.addConstr( lhs_expr, relation, rhs_expr, name) model.update()
def __init__(self, index: int, scenario: float, probability: float, cfg: Config): self.cfg = cfg self.probability = probability self.index = index self.scenario = scenario self.objective = QuadExpr() # model.ModelSense is minimization by default self.model = Model(f"base_problem_{self.index}") self.x_1 = self.model.addVar(ub=self.cfg.area, name="x_1") self.x_2 = self.model.addVar(ub=self.cfg.area, name="x_2") self.x_3 = self.model.addVar(ub=self.cfg.area, name="x_3") self.model.addConstr(self.x_1 + self.x_2 + self.x_3 <= self.cfg.area) self.objective.add(self.x_1 * self.cfg.wheat.plant_cost * self.probability) self.objective.add(self.x_2 * self.cfg.corn.plant_cost * self.probability) self.objective.add(self.x_3 * self.cfg.beet.plant_cost * self.probability) self._corn_variables_constraint() self._wheat_variables_constraint() self._beet_variables_constraint()
def __init__(self): self.model = Model("benders_sub_problem") self.x_1 = self.model.addVar(lb=0, name="x_1") self.x_2 = self.model.addVar(lb=0, name="x_2") self.x_3 = self.model.addVar(lb=0, name="x_3") self.x_4 = self.model.addVar(lb=0, name="x_4") self.x_5 = self.model.addVar(lb=0, name="x_5") v_1 = self.model.addVar(lb=0, name="v_1") self.model.addConstr(self.x_1 + self.x_4 + self.x_5 - v_1 <= 3) v_2 = self.model.addVar(lb=0, name="v_2") self.model.addConstr(2 * self.x_2 + 3 * self.x_4 - v_2 <= 12) v_3 = self.model.addVar(lb=0, name="v_3") self.model.addConstr(self.x_3 - 7 * self.x_5 - v_3 <= -16) self.x_hat_4 = None self.x_hat_5 = None self.model.setObjective( -2 * self.x_1 - self.x_2 + self.x_3 + BIG_M * v_1 + BIG_M * v_2 + BIG_M * v_3, GRB.MINIMIZE, )
class MasterProblem: def __init__(self): self.model = Model("benders_master_problem") self.x_4 = self.model.addVar(lb=0, name="x_4") self.x_5 = self.model.addVar(lb=0, name="x_5") self.phi = self.model.addVar(lb=-100 * 100 * 100, name="phi") self.model.addConstr(-self.x_4 + self.x_5 <= 2) self.model.setObjective( 3 * self.x_4 - 3 * self.x_5 + self.phi, GRB.MINIMIZE, ) def add_cut(self, lhs, pi_1, pi_2): self.model.addConstr( lhs <= self.phi - self.x_4 * pi_1 - self.x_5 * pi_2, name="cut") def solve(self): self.model.optimize() return ( self.model.objVal, self.x_4.x, self.x_5.x, )
def __init__(self, si: SolverInfo, budget, gurobi_params: Dict[str, Any] = None, ablation=False, overhead=False): self.gurobi_params = gurobi_params self.num_threads = self.gurobi_params.get('Threads', 1) self.budget = int(budget * MEM_GCD_MULTIPLIER * GB_TO_KB) self.si: SolverInfo = si self.solve_time = None self.ablation = ablation self.overhead = overhead V = self.si.loss + 1 T = len(self.si.nodes) - self.si.loss Y = 3 budget = self.budget self.m = Model("monet{}".format(self.budget)) if gurobi_params is not None: for k, v in gurobi_params.items(): setattr(self.m.Params, k, v) self.ram = np.array([math.ceil(self.si.nodes[i].mem*MEM_GCD_MULTIPLIER/1024) for i in self.si.nodes]) # Convert to KB self.cpu = dict(( i, [math.ceil(val*CPU_GCD_MULTIPLIER) for val in self.si.nodes[i].workspace_compute] ) for i in self.si.nodes) self.cpu_recompute = dict(( i, [math.ceil(val*CPU_GCD_MULTIPLIER) for val in self.si.nodes[i].recompute_workspace_compute] ) for i in self.si.nodes) self.cpu_inplace = dict(( i, [math.ceil(val*CPU_GCD_MULTIPLIER) for val in self.si.nodes[i].inplace_workspace_compute] ) for i in self.si.nodes) self.R = self.m.addVars(T, V, name="R", vtype=GRB.BINARY) # Recomputation self.P = self.m.addVars(T, V, name="P", vtype=GRB.BINARY) # In-memory self.S = self.m.addVars(T+1, V, name="S", vtype=GRB.BINARY) # Stored self.M = self.m.addVars(T, Y, name="M", vtype=GRB.BINARY) # Backward operator implementation self.SM = self.m.addVars(T, V, Y, name="SM", vtype=GRB.BINARY) # Linearization of S * M if self.si.select_conv_algo: self.RF = self.m.addVars(T, len(self.si.conv_list), self.si.num_conv_algos, name="RF", vtype=GRB.BINARY) # Conv operator implementations if self.si.do_inplace: self.IP = self.m.addVars(T, V, name="IP", vtype=GRB.BINARY) # In-place
class IandPModel: def __init__(self, instance): self.model = Model() self.vars = dict() self._set_model(instance) def _set_model(self, instance): T = instance.periods c = instance.c h = instance.h d = instance.d model = self.model x = model.addVars(range(T)) z = model.addVars(range(T)) model.addConstrs(z[t] == z[t - 1] + x[t] - d[t] for t in range(1, T)) model.addConstr(z[0] == x[0] - d[0]) obj = quicksum(c[t] * x[t] + h[t] * z[t] for t in range(T)) model.setObjective(obj, sense=GRB.MINIMIZE) self.vars = {'x': x, 'z': z} def solve(self): self.model.optimize()
def __build_base_model_for_hitting_set( self ) : if self._use_pulp: self.base_model = pulp.LpProblem( "min-cost-hitting-set", pulp.LpMinimize ) else: self.base_model = Model( "min-cost-hitting-set" ) self.base_model.setParam( "OutputFlag", 0 ) # variables -> one per action self.hs_vars = [] self.hs_coeffs = {} for idx in xrange( len(self.task.actions) ) : var_name = 'a_%d'%idx if self._use_pulp: self.hs_vars.append( pulp.LpVariable( var_name, 0, 1, cat = 'Integer' ) ) else: self.hs_vars.append( self.base_model.addVar( name=var_name, vtype=GRB.BINARY ) ) self.hs_coeffs[ var_name ] = self.task.actions[idx].cost if not self._use_pulp: self.base_model.update() # objective functions if self._use_pulp: obj = 0 for var in self.hs_vars: obj = (self.hs_coeffs[var.getName()] * var) + obj self.base_model.setObjective(obj) else: # MRJ: Support for non-unit costs, makes heuristic admissible if there are action costs self.base_model.setObjective( quicksum( self.hs_coeffs[a.getAttr('VarName')] * a for a in self.hs_vars ), GRB.MINIMIZE ) # MRJ: Assumes action have unit costs, makes heuristic inadmissible if there are action costs #self.base_model.setObjective( quicksum( a for a in self.hs_vars ), GRB.MINIMIZE ) self.base_model.update()
class RegressionModel: def __init__(self, instance): self.model = Model() self.vars = dict() self._set_model(instance) def _set_model(self, instance): model = self.model factors = range(instance.factors) obs = range(instance.obs) X = instance.X Y = instance.Y beta_0 = model.addVar(lb=-GRB.INFINITY) beta_1 = model.addVars(factors, lb=-GRB.INFINITY) error = quicksum((Y[i] - beta_0 - quicksum(beta_1[j] * X[i][j] for j in factors)) ** 2 for i in obs) model.setObjective(error, sense=GRB.MINIMIZE) self.vars['beta_0'] = beta_0 self.vars['beta_1'] = beta_1 def solve(self): self.model.optimize() m = list(map(lambda x: x.X, self.vars['beta_1'].values())) n = self.vars['beta_0'].X return m, n
def set_solution_size(model: Model, size: int) -> None: """ Set the number of solutions to be computed by optimizing the given model. For Gurobi only. """ if args.use_gurobi: model.setParam(GRB.param.PoolSearchMode, 2) model.setParam(GRB.param.PoolSolutions, size)
def init(self, lp): lp.build_original_model(data) lp.model.optimize() if lp.model.status == GRB.OPTIMAL: lp.get_value() number_of_invalid_paths = 0 for i in range(len(lp.routes)): if len(lp.routes[i]) == 2: number_of_invalid_paths += 1 if number_of_invalid_paths == 0: self.data.veh_num -= 1 lp.model = Model("original_model") lp = Bab_Vrptw(self.data) return self.init(lp) else: self.data.veh_num -= number_of_invalid_paths lp.model = Model("original_model") lp = Bab_Vrptw(self.data) return self.init(lp) else: data.veh_num += 1 lp.model = Model("original_model") lp = Bab_Vrptw(data) lp.build_original_model(data) lp.model.optimize() if lp.model.status == GRB.OPTIMAL: lp.get_value() return lp else: print("发现错误") return None
def get_iis_weight(self, gmodel: Model, iis_constrains: List[Constr]) -> int: weight_a, weight_b = 0, 0 for c in iis_constrains: weight_a += abs(gmodel.getCoeff(c, self.alpha_var)) weight_b += abs(gmodel.getCoeff(c, self.beta_var)) return weight_a + weight_b
def build_milp(self, model, **options): self.milp = Model(self.name) for param, value in options.items(): self.milp.setParam(param, value) # ... return self.milp
def __init__(self, name): Model.__init__(self, name) print str(self) self.testVar = 4 self.createVars() self.update() self.createObjectiveFunction() self.createConstraints()
def parse_results(model: gp.Model) -> None: objVal = model.getObjective().getValue() print("Get optimal Obj: {}".format(objVal)) print("Solution:") for name, val in zip(model.getAttr("varName"), model.getAttr("x")): print("Var {}: {}".format(name, val)) for con, val in zip(model.getAttr("constrName"), model.getAttr("Pi")): print("Dual var of {}: {}".format(con, val))
def analizar(subcarpeta: str): print(f"Analizando {subcarpeta}") if not os.path.exists(os.path.join(os.getcwd(), 'output')): os.makedirs(os.path.join(os.getcwd(), 'output')) if not os.path.exists(os.path.join(os.getcwd(), 'output', subcarpeta)): os.makedirs(os.path.join(os.getcwd(), 'output', subcarpeta)) if not os.path.exists( os.path.join(os.getcwd(), 'output', subcarpeta, 'restricciones')): os.makedirs( os.path.join(os.getcwd(), 'output', subcarpeta, 'restricciones')) if not os.path.exists( os.path.join(os.getcwd(), 'output', subcarpeta, 'resultados')): os.makedirs( os.path.join(os.getcwd(), 'output', subcarpeta, 'resultados')) if not os.path.exists( os.path.join(os.getcwd(), 'output', subcarpeta, 'variables')): os.makedirs( os.path.join(os.getcwd(), 'output', subcarpeta, 'variables')) if not os.path.exists( os.path.join(os.getcwd(), 'output', subcarpeta, 'valores')): os.makedirs(os.path.join(os.getcwd(), 'output', subcarpeta, 'valores')) # cargamos los parámetros. Estos deben venir de los datos. # Usamos pandas parametros_dict = cargar_datos(subcarpeta) # creamos el modelo m = Model() # cargamos las variables variables_dict = cargar_variables(m, parametros_dict) m.update() # cargamos las restricciones restricciones_dict = cargar_restricciones(m, variables_dict, parametros_dict) m.update() # cargamos la función objetivo cargar_funcion_objetivo(m, variables_dict, parametros_dict) m.update() # optimizamos m.optimize() guardar_variables(variables_dict, subcarpeta) guardar_restricciones(restricciones_dict, subcarpeta) guardar_fo(m.ObjVal, subcarpeta) # tabla de que contenido se libera que semana generar_graficos(subcarpeta) print(f"Analizado {subcarpeta}!") print("\n\n\n\n\n") return m
def __init__(self, model=None, env=None): Solver.__init__(self) if env: self.problem = GurobiModel(env=env) else: self.problem = GurobiModel() self.set_logging(False) self.set_parameters(default_parameters) if model: self.build_problem(model)
def def_PL(self): """ Definie le PL, variables/contraintes/objectifs """ model = Model("MR") self.set_vars(model) self.set_constraints(model) self.set_objectif(model) model.setParam("OutputFlag", False) return model
def OptimalTransportGurobi(H1, H2): n = len(H1) m = len(H2) mod = Model() # Parameters I = list(range(n)) J = (range(m)) # Variables x = {} for i in I: for j in J: x[i,j] = mod.addVar(obj=D(H1[i], H2[j])) # Constraints on the supports for i in I: mod.addConstr(quicksum(x[i,j] for j in J) == 1) for j in J: mod.addConstr(quicksum(x[i,j] for i in I) == 1) # Train: Solve the model mod.optimize() ColMap = [] for i in I: for j in J: if x[i,j].X > 0.5: ColMap.append(j) return ColMap
def optimizeGEM(GEM, obj_rxn): """ Plain old FBA using cobra model with gurobi. I made this function because the cobra optimize function gives error when used on split, irreversible model """ model = Model('FBA_model') GEM_rxn_ids = [rxn.id for rxn in GEM.reactions] S = cobra.util.array.create_stoichiometric_matrix(GEM, array_type='dense') # Add variables v = {} for rxn in GEM.reactions: var_id = f'v_{rxn.id}' x = model.addVar(lb=rxn.lower_bound, ub=rxn.upper_bound, obj=0.0, vtype=GRB.CONTINUOUS, name=var_id) v[var_id] = x # Add constraints for i, row in enumerate(S): c = '' for j, coeff in enumerate(row): rxn_id = GEM_rxn_ids[j] if coeff != 0: c += f'{coeff} * v["v_{rxn_id}"] +' c = c[:-1] c += '== 0' model.addConstr(eval(c), f'mass_balance_{GEM.metabolites[i].id}') # Set Objective model.setObjective(v['v_' + obj_rxn], GRB.MAXIMIZE) model.optimize() return model
def generate_row_model(row_matrix, b, v, c): """ rows_matrix: The matrix, represented as a list of rows b: List of variables in b v: The target vector c: The weights of each column """ # Initializes a model mdl = Model('persistenthomologylocalization') # Add matrix variables x = mdl.addVars(list(b), vtype=GRB.BINARY) # Add the dummy variable needed to do arithmetics mod 2 y = mdl.addVars(list(range(len(row_matrix))), vtype=GRB.INTEGER) # Set model to minimization mdl.modelSense = GRB.MINIMIZE # Set objective function to minimize mdl.setObjective(quicksum(x[j] * c[j] for j in b)) # Set the constrains for i in list(range(len(row_matrix))): mdl.addConstr(quicksum(x[j] for j in row_matrix[i]) + v[i] == y[i] * 2) return mdl, x, y
def _construct_max_flow_lp(self, G, edge_to_paths, num_total_paths): m = Model('max-flow') # Create variables: one for each path path_vars = m.addVars(num_total_paths, vtype=GRB.CONTINUOUS, lb=0.0, name='f') obj = quicksum(path_vars) m.setObjective(obj, GRB.MAXIMIZE) # Add demand constraints commod_id_to_path_inds = {} for k, d_k, path_inds in self.commodities: commod_id_to_path_inds[k] = path_inds m.addConstr(quicksum(path_vars[p] for p in path_inds) <= d_k) # Add edge capacity constraints for u, v, c_e in G.edges.data('capacity'): paths = edge_to_paths[(u, v)] constr_vars = [path_vars[p] for p in paths] m.addConstr(quicksum(constr_vars) <= c_e) return LpSolver(m, None, self.DEBUG, self.VERBOSE, self.out)
def construct_lp_model(c, A, d): from gurobipy import Model, LinExpr, GRB # A = numpy.array (matrix) # c = numpy.array (vector) # d = numpy.array (vector) k, n = A.shape # Creation of the gurobi model m = Model("sp") # Variables x = list() for i in range(n): x.append(m.addVar(lb=-GRB.INFINITY, ub=GRB.INFINITY, name='x_%d' % i)) # Objective Function objExpr = LinExpr() for i in range(n): objExpr.add(x[i], c[i]) m.setObjective(objExpr, GRB.MAXIMIZE) # Constraints expr = {} for j in range(k): expr = LinExpr() for i in range(n): expr.add(x[i], A[j, i]) m.addConstr(expr, GRB.LESS_EQUAL, d[j]) # Update the model to add new entries m.update() return m
def create_problem(cobra_model, objective_sense="maximize"): lp = Model("cobra") lp.Params.OutputFlag = 0 if objective_sense == 'maximize': objective_sign = -1.0 elif objective_sense == 'minimize': objective_sign = 1.0 else: raise ValueError("objective_sense must be 'maximize' or 'minimize'") # create metabolites/constraints metabolite_constraints = {} for metabolite in cobra_model.metabolites: metabolite_constraints[metabolite] = \ lp.addConstr(0.0, sense_dict[metabolite._constraint_sense], metabolite._bound, metabolite.id) lp.update() # create reactions/variables along with S matrix for j, reaction in enumerate(cobra_model.reactions): constraints = [metabolite_constraints[i] \ for i in reaction._metabolites] stoichiometry = reaction._metabolites.values() lp.addVar( lb=float(reaction.lower_bound), ub=float(reaction.upper_bound), obj=objective_sign * reaction.objective_coefficient, name=reaction.id, vtype=variable_kind_dict[reaction.variable_kind], column=Column(stoichiometry, constraints)) lp.update() return lp
class optimization_model: def __init__(self, scenario): self.scenario = scenario self.model = Model('network_optimization') def create_start_time_variables(self): self.S = self.model.addVars(self.scenario.settings.number_of_tasks, vtype = GRB.INTEGER, lb = 0, ub = self.scenario.settings.number_of_time_periods, name = 'S') def create_end_time_variables(self): self.C = self.model.addVars(self.scenario.settings.number_of_tasks, vtype = GRB.INTEGER, lb = 0, ub = self.scenario.settings.number_of_time_periods, name = 'C') def create_work_time_variables(self): self.X = self.model.addVars(self.scenario.settings.number_of_tasks,self.scenario.settings.number_of_modes,self.scenario.settings.number_of_time_periods, vtype = GRB.BINARY, name = 'X') def create_tech_assignment_variables(self): self.V = self.model.addVars(self.scenario.settings.number_of_techs,self.scenario.settings.number_of_tasks,self.scenario.settings.number_of_time_periods, vtype = GRB.BINARY, name = 'V') def add_precedence_constraints(self): for task in self.scenario.task_list: for successor in task.successor_list: self.model.addConstr(self.S[successor] - self.C[task.task_index], GRB.GREATER_EQUAL, 1, name = "Precedence.%d.%d" % (successor,task.task_index)) def set_objective_makespan(self): self.model.setObjective(self.C[self.scenario.task_list[-1].task_index], sense = GRB.MINIMIZE) def create_model_variables(self): self.create_start_time_variables() self.create_end_time_variables() self.create_work_time_variables() self.create_tech_assignment_variables() def add_model_constraints(self): self.add_precedence_constraints() def set_model_objective(self): self.set_objective_makespan() def write_model(self): self.model.write("/Users/yashpatil/Desktop/Personal Github Projects/Multimode_Network_Assignment/model_optimizationFiles/model_formulation.lp")
def __init__(self, cfg: Config): self.cfg = cfg # model.ModelSense is minimization by default self.model = Model("beet_sub_problem") self.x_3 = self.model.addVar(ub=self.cfg.area, name="x_3") probability = 1 / len(self.cfg.scenarios) for index, scenario in enumerate(self.cfg.scenarios): self._variables_constraint(index, scenario, probability)
def __init__( self, g: DFGraph, budget: int, eps_noise=None, model_file=None, remote=False, gurobi_params: Dict[str, Any] = None, cpu_fwd_factor: int = 2, ): self.cpu_fwd_factor = cpu_fwd_factor self.logger = logging.getLogger(__name__) self.remote = remote self.profiler = functools.partial(Timer, print_results=True) self.gurobi_params = gurobi_params self.num_threads = self.gurobi_params.get("Threads", 1) self.model_file = model_file self.eps_noise = eps_noise self.budget = budget self.g = g self.solve_time = None self.init_constraints = [] # used for seeding the model self.m = Model("checkpointmip_gc_maxbs_{}_{}".format(self.g.size, self.budget)) if gurobi_params is not None: for k, v in gurobi_params.items(): setattr(self.m.Params, k, v) T = self.g.size CPU_VALS = list(self.g.cost_cpu.values()) RAM_VALS = list(self.g.cost_ram.values()) self.logger.info( "RAM: [{:.2E}, {:.2E}], {:.2E} +- {:.2E}".format( np.min(RAM_VALS), np.max(RAM_VALS), np.mean(RAM_VALS), np.std(RAM_VALS) ) ) self.logger.info( "CPU: [{:.2E}, {:.2E}], {:.2E} +- {:.2E}".format( np.min(CPU_VALS), np.max(CPU_VALS), np.mean(CPU_VALS), np.std(CPU_VALS) ) ) self.ram_gcd = int(max(self.g.ram_gcd(self.budget), 1)) self.cpu_gcd = int(max(self.g.cpu_gcd(), 1)) self.logger.info("ram_gcd = {} cpu_gcd = {}".format(self.ram_gcd, self.cpu_gcd)) self.batch_size = self.m.addVar(lb=1, ub=1024 * 16, name="batch_size") self.R = self.m.addVars(T, T, name="R", vtype=GRB.BINARY) self.S = self.m.addVars(T, T, name="S", vtype=GRB.BINARY) self.Free_E = self.m.addVars(T, len(self.g.edge_list), name="FREE_E", vtype=GRB.BINARY) self.U = self.m.addVars(T, T, name="U", lb=0.0, ub=self.budget) for x in range(T): for y in range(T): self.m.addLConstr(self.U[x, y], GRB.GREATER_EQUAL, 0) self.m.addLConstr(self.U[x, y], GRB.LESS_EQUAL, float(budget) / self.ram_gcd)
def __init__(self, samples, delta=1.0): self.n_nodes = samples.n_nodes self.n_samples = samples.n_samples self.delta = delta self.B = samples.B self.T = samples.T self.F = samples.F self.model = Model('DPSL') self.create_model()
def ilp_node_reachability(reachability_dic, max_delay=180, log_path=None): # List of nodes ids node_ids = sorted(list(reachability_dic.keys())) #node_ids = node_ids[:100] try: # Create a new model m = Model("region_centers") if log_path: m.Params.LogFile = '{}/region_centers_{}.log'.format( log_path, max_delay) # xi = 1, if vertex Vi is used as a region center and 0 otherwise x = m.addVars(node_ids, vtype=GRB.BINARY, name="x") # Ensures that every node in the road network graph is reachable # within 'max_delay' travel time by at least one region center # selected from the nodes in the graph. # To extract the region centers, we select from V all vertices # V[i] such that x[i] = 1. for d in node_ids: m.addConstr( quicksum(x[o] * is_reachable(reachability_dic, o, d, max_delay) for o in node_ids) >= 1) # Set objective m.setObjective(quicksum(x), GRB.MINIMIZE) # Solve m.optimize() region_centers = list() if m.status == GRB.Status.OPTIMAL: var_x = m.getAttr('x', x) for n in node_ids: if var_x[n] > 0.0001: region_centers.append(n) return region_centers else: print('No solution') return None except GurobiError as e: print('Error code ' + str(e.errno) + ": " + str(e)) except AttributeError as e: print('Encountered an attribute error:' + str(e))
def add_binary_switch(m: gModel, label: str, v1: float, v2: float, delta: gVar, K: float) -> gVar: y = m.addVar(lb=-GRB.INFINITY, ub=GRB.INFINITY, name=label) m.addConstr(y <= v1 + delta * K) m.addConstr(y >= v1 - delta * K) m.addConstr(y <= v2 + (1 - delta) * K) m.addConstr(y >= v2 - (1 - delta) * K) return y
def __init__(self, Data): """Formulate the master problem. INPUTS Data :: object, classes.Data; problem data. """ self.Data = Data self.duals = [] self.master = Model("master LP") # Init master model self.master.Params.OutputFlag = 0 # No output self._formulate_master()
def create_problem(cobra_model, objective_sense="maximize"): lp = Model("cobra") lp.Params.OutputFlag = 0 if objective_sense == "maximize": objective_sign = -1.0 elif objective_sense == "minimize": objective_sign = 1.0 else: raise ValueError("objective_sense must be 'maximize' or 'minimize'") # create metabolites/constraints metabolite_constraints = {} for metabolite in cobra_model.metabolites: metabolite_constraints[metabolite] = lp.addConstr( 0.0, sense_dict[metabolite._constraint_sense], metabolite._bound, metabolite.id ) lp.update() # create reactions/variables along with S matrix for j, reaction in enumerate(cobra_model.reactions): constraints = [metabolite_constraints[i] for i in reaction._metabolites] stoichiometry = reaction._metabolites.values() lp.addVar( lb=float(reaction.lower_bound), ub=float(reaction.upper_bound), obj=objective_sign * reaction.objective_coefficient, name=reaction.id, vtype=variable_kind_dict[reaction.variable_kind], column=Column(stoichiometry, constraints), ) lp.update() return lp
def __loadModel(self): # Create optimization model self.__model = Model('PathBackup') # Auxiliary variables for SOCP reformulation U = {} R = {} # Create variables for i,j in self.__links: self.__BackupCapacity[i,j] = self.__model.addVar(lb=0, obj=1, name='Backup_Capacity[%s,%s]' % (i, j)) self.__model.update() for p in self.__paths: #LP Relaxation #self.__bPath[self.__paths.index(p)] = self.__model.addVar(lb=0,obj=1,name='Backup_Path[%s]' % (self.__paths.index(p))) self.__bPath[self.__paths.index(p)] = self.__model.addVar(vtype=GRB.BINARY,obj=1,name='Backup_Path[%s]' % (self.__paths.index(p))) self.__model.update() for i,j in self.__links: U[i,j] = self.__model.addVar(obj=1,name='U[%s,%s]' % (i, j)) self.__model.update() for i,j in self.__links: for s,d in self.__links: R[i,j,s,d] = self.__model.addVar(obj=1,name='R[%s,%s,%s,%s]' % (i,j,s,d)) self.__model.update() self.__model.modelSense = GRB.MINIMIZE self.__model.setObjective(quicksum(self.__BackupCapacity[i,j] for i,j in self.__links)) self.__model.update() #------------------------------------------------------------------------# # Constraints definition # # # # # #------------------------------------------------------------------------# # Link capacity constraints for i,j in self.__links: self.__model.addConstr(self.__BackupCapacity[i,j] >= quicksum(self.__mean[s,d]*quicksum(self.__bPath[self.__paths.index(p)] for p in self.__Pij[i,j,s,d]) for s,d in self.__links) + U[i,j]*self.__invstd,'[CONST]Link_Cap[%s][%s]' % (i, j)) self.__model.update() # SCOP Reformulation Constraints for i,j in self.__links: self.__model.addConstr(quicksum(R[i,j,s,d]*R[i,j,s,d] for s,d in self.__links) <= U[i,j]*U[i,j],'[CONST]SCOP1[%s][%s]' % (i, j)) self.__model.update() # SCOP Reformulation Constraints for i,j in self.__links: for s,d in self.__links: self.__model.addConstr(self.__std[s,d]*quicksum(self.__bPath[self.__paths.index(p)] for p in self.__Pij[i,j,s,d]) == R[i,j,s,d],'[CONST]SCOP2[%s][%s][%s][%s]' % (i,j,s,d)) self.__model.update() # Unique path for s,d in self.__links: self.__model.addConstr(quicksum(self.__bPath[self.__paths.index(p)] for p in self.__Psd[s,d]) == 1,'UniquePath[%s,%s]' % (s, d)) self.__model.update()
def create_problem(cobra_model, quadratic_component=None, **kwargs): """Solver-specific method for constructing a solver problem from a cobra.Model. This can be tuned for performance using kwargs """ lp = Model("") the_parameters = parameter_defaults if kwargs: the_parameters = parameter_defaults.copy() the_parameters.update(kwargs) # Set verbosity first to quiet infos on parameter changes if "verbose" in the_parameters: set_parameter(lp, "verbose", the_parameters["verbose"]) for k, v in iteritems(the_parameters): set_parameter(lp, k, v) # Create variables #TODO: Speed this up variable_list = [lp.addVar(_float(x.lower_bound), _float(x.upper_bound), float(x.objective_coefficient), variable_kind_dict[x.variable_kind], str(i)) for i, x in enumerate(cobra_model.reactions)] reaction_to_variable = dict(zip(cobra_model.reactions, variable_list)) # Integrate new variables lp.update() #Constraints are based on mass balance #Construct the lin expression lists and then add #TODO: Speed this up as it takes about .18 seconds #HERE for i, the_metabolite in enumerate(cobra_model.metabolites): constraint_coefficients = [] constraint_variables = [] for the_reaction in the_metabolite._reaction: constraint_coefficients.append(_float(the_reaction._metabolites[the_metabolite])) constraint_variables.append(reaction_to_variable[the_reaction]) #Add the metabolite to the problem lp.addConstr(LinExpr(constraint_coefficients, constraint_variables), sense_dict[the_metabolite._constraint_sense.upper()], the_metabolite._bound, str(i)) # Set objective to quadratic program if quadratic_component is not None: set_quadratic_objective(lp, quadratic_component) lp.update() return(lp)
def __init_prob(self): # Modify parameters logging.info("Generating initial marking problem") self.prob = Model("SC1") # Gurobi parameters: if not self.verbose: self.prob.params.OutputFlag = 0 try: os.remove("gurobi.log") except OSError: pass self.prob.params.Threads = 4
def _init_LP(self): if self._lp_inited: return logging.debug('Init LP') self.lp = LPModel('estep') self.lp.setAttr("modelSense", 1) # minimzation self.alpha = {} beta2 = {} beta3 = {} # instantiate vars logging.debug('Init LP - create vars') for a in self.author_graph: self.alpha[a] = {} for p in self.parts: self.alpha[a][p] = self.lp.addVar(lb=0.0) for a, b in self.author_graph.edges(): beta2[(a, b)] = self.lp.addVar() beta3[(a, b)] = {} for p in self.parts: beta3[(a, b)][p] = self.lp.addVar(lb=0.0) # integrate added variables into the model self.lp.update() # add constraints once during this init # alphas are indicator vars logging.debug('Init LP - indiv constraints') ones_arr = [1.0] * len(self.parts) for a in self.author_graph: self.lp.addConstr(LinExpr(ones_arr, self.alpha[a].values()), GRB.EQUAL, 1.0) # beta2 is the sum of beta3s logging.debug('Init LP - pair constraints') pt_five_array = [0.5] * len(self.parts) for a, b in self.author_graph.edges(): self.lp.addConstr(LinExpr(pt_five_array, beta3[(a, b)].values()), GRB.EQUAL, beta2[(a, b)]) for p in self.parts: self.lp.addConstr(LinExpr([1.0, -1.0], [self.alpha[a][p], self.alpha[b][p]]), GRB.LESS_EQUAL, beta3[(a, b)][p]) self.lp.addConstr(LinExpr([-1.0, 1.0], [self.alpha[a][p], self.alpha[b][p]]), GRB.LESS_EQUAL, beta3[(a, b)][p]) self.lp.update() # calculate pairwise potentials part of the objective # the optimization is to minimize negated log-likelihood = maximize the log-likelihood logging.debug('Obj func - pair potentials') s = np.log(1 - self.TAU) - np.log(self.TAU) lpcoeffs, lpvars = [], [] for a, b in self.author_graph.edges(): lpcoeffs.append(-self.author_graph[a][b]['weight'] * s) lpvars.append(beta2[(a, b)]) self.objF_pair = LinExpr(list(lpcoeffs), list(lpvars)) self._lp_inited = True logging.debug('Init LP Done')
def __loadModel(self,imp_samp, backup_link,link_capacity): # Create optimization model self.__model = Model('Backup') for i,j in self.__links: for k in range(self.__N): self.__z[k,i,j] = self.__model.addVar(lb=0,name='z[%s][%s][%s]' % (k,i,j)) self.__model.update() for i,j in self.__links: self.__z0[i,j] = self.__model.addVar(lb=-GRB.INFINITY,name='z0[%s][%s]' %(i,j)) self.__model.update() for i,j in self.__links: self.__q[i,j] = self.__model.addVar(lb=-GRB.INFINITY,name='q[%s][%s]' %(i,j)) self.__model.update() self.__model.modelSense = GRB.MINIMIZE self.__model.setObjective(quicksum(self.__q[i,j] for i,j in self.__links)) self.__model.update() #------------------------------------------------------------------------# # Constraints definition # # # # # #------------------------------------------------------------------------# # Buffer probability I for i,j in self.__links: self.__model.addConstr(self.__z0[i,j] + 1/(self.__N*self.__epsilon)*quicksum(self.__z[k,i,j]*imp_samp[k] for (k) in range(self.__N)) <= self.__q[i,j],'[CONST]Buffer_Prob_I[%s][%s]'%(i,j)) self.__model.update() # Link capacity constraints for i,j in self.__links: for k in range(self.__N): self.__model.addConstr((quicksum(backup_link[i,j,s,d]*self.__capacity[k,s,d] for s,d in self.__links) - link_capacity[i,j] - self.__z0[i,j]) <= self.__z[k,i,j],'[CONST]Buffer_Prob_II[%s][%s][%s]' % (k,i,j)) self.__model.update() # Link capacity constraints for i,j in self.__links: for k in range(self.__N): self.__model.addConstr(self.__z[k,i,j] >= 0,'[CONST]Buffer_Prob_III[%s][%s][%s]' % (k,i,j)) self.__model.update()
def __init__(self, length): """Initialize model, note and chord variables, and constraints for notes and chord constraints.""" self.model = Model("harmony") self.length = length config = load_source("config", join(abspath(dirname(__file__)), "config.py")) config.length = self.length config.model = self.model self.notes = Notes(config) config.notes = self.notes self.chords = Chords(config)
def __init__(self, json_data): self.m = Model('mip1.log') self.solution_matrix = None # Load from JSON self.all_data = json_data self.student_ids = [int(k) for k in json_data['students'].keys()] self.course_ids = [int(k) for k in json_data['courses'].keys()] self.semester_ids = [int(k) for k in json_data['semesters'].keys()] self.dependencies = [(d['first_course'], d['second_course']) for d in json_data['course_dependencies']] self.student_demand = defaultdict(lambda: False) for sd in json_data['student_demand']: self.student_demand[sd['student_id'], sd['course_id'], sd['semester_id']] = True self.instructor_availability = defaultdict(lambda: False) for ia in json_data['instructor_pool']: self.instructor_availability[ia['instructor_id'], ia['course_id'], ia['semester_id']] = True self.instructor_ids = [s['instructor_id'] for s in json_data['instructor_pool']]
class GurobiSolver(Solver): """ Implements the solver interface using gurobipy. """ def __init__(self): Solver.__init__(self) self.problem = GurobiModel() def __getstate__(self): tmp_file = tempfile.mktemp(suffix=".lp") self.problem.update() self.problem.write(tmp_file) cplex_form = open(tmp_file).read() repr_dict = {'var_ids': self.var_ids, 'constr_ids': self.constr_ids, 'cplex_form': cplex_form} return repr_dict def __setstate__(self, repr_dict): tmp_file = tempfile.mktemp(suffix=".lp") open(tmp_file, 'w').write(repr_dict['cplex_form']) self.problem = read(tmp_file) self.var_ids = repr_dict['var_ids'] self.constr_ids = repr_dict['constr_ids'] def add_variable(self, var_id, lb=None, ub=None, vartype=VarType.CONTINUOUS, persistent=True, update_problem=True): """ Add a variable to the current problem. Arguments: var_id : str -- variable identifier lb : float -- lower bound ub : float -- upper bound vartype : VarType -- variable type (default: CONTINUOUS) persistent : bool -- if the variable should be reused for multiple calls (default: true) update_problem : bool -- update problem immediately (default: True) """ lb = lb if lb is not None else -GRB.INFINITY ub = ub if ub is not None else GRB.INFINITY map_types = {VarType.BINARY: GRB.BINARY, VarType.INTEGER: GRB.INTEGER, VarType.CONTINUOUS: GRB.CONTINUOUS} if var_id in self.var_ids: var = self.problem.getVarByName(var_id) var.setAttr('lb', lb) var.setAttr('ub', ub) var.setAttr('vtype', map_types[vartype]) else: self.problem.addVar(name=var_id, lb=lb, ub=ub, vtype=map_types[vartype]) self.var_ids.append(var_id) if not persistent: self.temp_vars.add(var_id) if update_problem: self.problem.update() def add_constraint(self, constr_id, lhs, sense='=', rhs=0, persistent=True, update_problem=True): """ Add a variable to the current problem. Arguments: constr_id : str -- constraint identifier lhs : list [of (str, float)] -- variables and respective coefficients sense : {'<', '=', '>'} -- default '=' rhs : float -- right-hand side of equation (default: 0) persistent : bool -- if the variable should be reused for multiple calls (default: True) update_problem : bool -- update problem immediately (default: True) """ grb_sense = {'=': GRB.EQUAL, '<': GRB.LESS_EQUAL, '>': GRB.GREATER_EQUAL} if constr_id in self.constr_ids: constr = self.problem.getConstrByName(constr_id) self.problem.remove(constr) expr = quicksum([coeff * self.problem.getVarByName(r_id) for r_id, coeff in lhs if coeff]) self.problem.addConstr(expr, grb_sense[sense], rhs, constr_id) self.constr_ids.append(constr_id) if not persistent: self.temp_constrs.add(constr_id) if update_problem: self.problem.update() def remove_variable(self, var_id): """ Remove a variable from the current problem. Arguments: var_id : str -- variable identifier """ if var_id in self.var_ids: self.problem.remove(self.problem.getVarByName(var_id)) self.var_ids.remove(var_id) def remove_constraint(self, constr_id): """ Remove a constraint from the current problem. Arguments: constr_id : str -- constraint identifier """ if constr_id in self.constr_ids: self.problem.remove(self.problem.getConstrByName(constr_id)) self.constr_ids.remove(constr_id) def update(self): """ Update internal structure. Used for efficient lazy updating. """ self.problem.update() def solve_lp(self, objective, model=None, constraints=None, get_shadow_prices=False, get_reduced_costs=False): """ Solve an LP optimization problem. Arguments: objective : dict (of str to float) -- reaction ids in the objective function and respective coefficients, the sense is maximization by default model : ConstraintBasedModel -- model (optional, leave blank to reuse previous model structure) constraints : dict (of str to (float, float)) -- environmental or additional constraints (optional) get_shadow_prices : bool -- return shadow price information if available (optional, default: False) get_reduced_costs : bool -- return reduced costs information if available (optional, default: False) Returns: Solution """ return self._generic_solve(None, objective, GRB.MAXIMIZE, model, constraints, get_shadow_prices, get_reduced_costs) def solve_qp(self, quad_obj, lin_obj, model=None, constraints=None, get_shadow_prices=False, get_reduced_costs=False): """ Solve an LP optimization problem. Arguments: quad_obj : dict (of (str, str) to float) -- map reaction pairs to respective coefficients lin_obj : dict (of str to float) -- map single reaction ids to respective linear coefficients model : ConstraintBasedModel -- model (optional, leave blank to reuse previous model structure) constraints : dict (of str to (float, float)) -- overriding constraints (optional) get_shadow_prices : bool -- return shadow price information if available (default: False) get_reduced_costs : bool -- return reduced costs information if available (default: False) Returns: Solution """ return self._generic_solve(quad_obj, lin_obj, GRB.MINIMIZE, model, constraints, get_shadow_prices, get_reduced_costs) def _generic_solve(self, quad_obj, lin_obj, sense, model=None, constraints=None, get_shadow_prices=False, get_reduced_costs=False): if model: self.build_problem(model) problem = self.problem if constraints: old_constraints = {} for r_id, (lb, ub) in constraints.items(): lpvar = problem.getVarByName(r_id) old_constraints[r_id] = (lpvar.lb, lpvar.ub) lpvar.lb = lb if lb is not None else -GRB.INFINITY lpvar.ub = ub if ub is not None else GRB.INFINITY problem.update() #create objective function quad_obj_expr = [q * problem.getVarByName(r_id1) * problem.getVarByName(r_id2) for (r_id1, r_id2), q in quad_obj.items() if q] if quad_obj else [] lin_obj_expr = [f * problem.getVarByName(r_id) for r_id, f in lin_obj.items() if f] if lin_obj else [] obj_expr = quicksum(quad_obj_expr + lin_obj_expr) problem.setObjective(obj_expr, sense) problem.update() # from datetime import datetime # self.problem.write("problem_{}.lp".format(str(datetime.now()))) #run the optimization problem.optimize() status = status_mapping[problem.status] if problem.status in status_mapping else Status.UNKNOWN message = str(problem.status) if status == Status.OPTIMAL: fobj = problem.ObjVal values = OrderedDict([(r_id, problem.getVarByName(r_id).X) for r_id in self.var_ids]) #if metabolite is disconnected no constraint will exist shadow_prices = OrderedDict([(m_id, problem.getConstrByName(m_id).Pi) for m_id in self.constr_ids if problem.getConstrByName(m_id)]) if get_shadow_prices else None reduced_costs = OrderedDict([(r_id, problem.getVarByName(r_id).RC) for r_id in self.var_ids]) if get_reduced_costs else None solution = Solution(status, message, fobj, values, shadow_prices, reduced_costs) else: solution = Solution(status, message) #reset old constraints because temporary constraints should not be persistent if constraints: for r_id, (lb, ub) in old_constraints.items(): lpvar = problem.getVarByName(r_id) lpvar.lb, lpvar.ub = lb, ub problem.update() return solution
def cycle_milp(A, C, k, gap): n = A.shape[0] t_0 = time.clock() _ = '*' m = Model() m.modelsense = GRB.MAXIMIZE m.params.mipgap = gap cycles = [] vars = [] cycles_grouped = [[] for i in range(n)] vars_grouped = [[] for i in range(n)] print('[%.1f] Generating variables...' % (time.clock() - t_0)) print('i = ', end='') for i in range(n): for cycle in dfs_cycles(i, A, k): w = sum([2 if j in C else 1 for j in cycle]) var = m.addVar(vtype=GRB.BINARY, obj=w) vars.append(var) cycles.append(cycle) cycles_grouped[i].append(cycle) vars_grouped[i].append(var) for j in cycle: if j > i: vars_grouped[j].append(var) cycles_grouped[j].append(cycle) if (i + 1) % 10 == 0: print(i + 1) m.update() print('[%.1f] Generated variables...' % (time.clock() - t_0)) print('[%.1f] Generating constraints...' % (time.clock() - t_0)) for i in range(n): vars_i = vars_grouped[i] lhs = LinExpr() ones = [1.0]*len(vars_i) lhs.addTerms(ones, vars_i) m.addConstr(lhs <= 1.0) print('[%.1f] Generated constraints...' % (time.clock() - t_0)) print('[%.1f] Begin Optimizing %d vertex %d cycle model' % (time.clock() - t_0, n, len(cycles))) m.update() m.optimize() m.update() print('[%.1f] Finished Optimizing' % (time.clock() - t_0)) print('[%.1f] Building cycles...' % (time.clock() - t_0)) final_cycles = [] for i in range(len(vars)): var = vars[i] if var.x == 1.0: cycle = cycles[i] final_cycles.append(cycle) print('[%.1f] Finished building cycles' % (time.clock() - t_0)) return final_cycles, m.objval
def constantino(A, C, k, gap): """ Polynomial-sized CCMcP Edge-Extended Model See Constantino et al. (2013) """ t_0 = time.clock() _ = '*' m = Model() m.modelsense = GRB.MAXIMIZE m.params.mipgap = gap # m.params.timelimit = 60 * 60 # m.params.nodefilestart = 1.0 # m.params.nodefiledir = './.nodefiledir' # m.params.presparsify = 0 # m.params.presolve = 0 n = A.shape[0] vars = {} edges = tuplelist() print('[%.1f] Generating variables...' % (time.clock() - t_0)) # Variables for l in range(n): for i in range(l, n): for j in range(l, n): if A[i, j] == 1: e = (l, i, j) edges.append(e) w = 2 if j in C else 1 var = m.addVar(vtype=GRB.BINARY, obj=w) vars[e] = var if l % 100 == 0 and l != 0: print('[%.1f] l = %d' % (time.clock() - t_0, l)) m.update() print('[%.1f] Generated variables' % (time.clock() - t_0)) print('[%.1f] Adding flow constraints...' % (time.clock() - t_0)) # Constraint (2): Flow in = Flow out for l in range(n): for i in range(l, n): # Flow in lhs_vars = [vars[e] for e in edges.select(l, _, i)] ones = [1.0]*len(lhs_vars) lhs = LinExpr() lhs.addTerms(ones, lhs_vars) # Flow out rhs_vars = [vars[e] for e in edges.select(l, i, _)] ones = [1.0]*len(rhs_vars) rhs = LinExpr() rhs.addTerms(ones, rhs_vars) # Flow in = Flow out m.addConstr(lhs == rhs) if l % 100 == 0 and l != 0: print('[%.1f] l = %d' % (time.clock() - t_0, l)) print('[%.1f] Added flow constraints' % (time.clock() - t_0)) print('[%.1f] Adding cycle vertex constraints...' % (time.clock() - t_0)) # Constraint (3): Use a vertex only once per cycle for i in range(n): c_vars = [vars[e] for e in edges.select(_, i, _)] ones = [1.0]*len(c_vars) expr = LinExpr() expr.addTerms(ones, c_vars) m.addConstr(expr <= 1.0) if i % 100 == 0 and i != 0: print('[%.1f] V_i = %d' % (time.clock() - t_0, i)) print('[%.1f] Added cycle vertex constraints' % (time.clock() - t_0)) print('[%.1f] Adding cycle cardinality constraints...' % (time.clock() - t_0)) # Constraint (4): Limit cardinality of cycles to k for l in range(n): c_vars = [vars[e] for e in edges.select(l, _, _)] ones = [1.0]*len(c_vars) expr = LinExpr() expr.addTerms(ones, c_vars) m.addConstr(expr <= k) if l % 100 == 0 and l != 0: print('[%.1f] l = %d' % (time.clock() - t_0, l)) print('[%.1f] Added cycle cardinality constraints' % (time.clock() - t_0)) print('[%.1f] Adding cycle index constraints...' % (time.clock() - t_0)) # Constraint (5): Cycle index is smallest vertex-index for l in range(n): rhs_vars = [vars[e] for e in edges.select(l, l, _)] ones = [1.0]*len(rhs_vars) rhs = LinExpr() rhs.addTerms(ones, rhs_vars) for i in range(l+1, n): lhs_vars = [vars[e] for e in edges.select(l, i, _)] if len(lhs_vars) > 0: ones = [1.0]*len(lhs_vars) lhs = LinExpr() lhs.addTerms(ones, lhs_vars) m.addConstr(lhs <= rhs) if l % 100 == 0 and l != 0: print('[%.1f] l = %d' % (time.clock() - t_0, l)) print('[%.1f] Added cycle index constraints...' % (time.clock() - t_0)) print('[%.1f] Begin Optimizing %d vertex model' % (time.clock() - t_0, n)) m.optimize() m.update() print('[%.1f] Finished Optimizing' % (time.clock() - t_0)) print('[%.1f] Building cycles...' % (time.clock() - t_0)) cycles = [] for l in range(n): c_edges = [(e[1], e[2]) for e in edges.select(l, _, _) if vars[e].x == 1.0] cycles.extend(cycles_from_edges(c_edges)) print('[%.1f] Finished building cycles' % (time.clock() - t_0)) return cycles, m.objval
def lazy_cycle_constraint(A, C, k, gap): """ Lazily generate cycle constraints as potential feasible solutions are generated. """ _ = '*' m = Model() m.modelsense = GRB.MAXIMIZE m.params.mipgap = gap m.params.timelimit = 5 * 60 * 60 m.params.lazyconstraints = 1 n = A.shape[0] edges = tuplelist() vars = {} for i in range(n): for j in range(n): if A[i, j] == 1: e = (i, j) edges.append(e) w = 2 if j in C else 1 var = m.addVar(vtype=GRB.BINARY, obj=w) vars[e] = var m.update() # flow constraints for i in range(n): out_vars = [vars[e] for e in edges.select(i, _)] out_ones = [1.0]*len(out_vars) out_expr = LinExpr() out_expr.addTerms(out_ones, out_vars) in_vars = [vars[e] for e in edges.select(_, i)] in_ones = [1.0]*len(in_vars) in_expr = LinExpr() in_expr.addTerms(in_ones, in_vars) m.addConstr(in_expr <= 1) m.addConstr(out_expr == in_expr) m.update() ith_cycle = 0 def callback(model, where): if where == GRB.Callback.MIPSOL: sols = model.cbGetSolution([vars[e] for e in edges]) c_edges = [edges[i] for i in range(len(edges)) if sols[i] > 0.5] cycles = cycles_from_edges(c_edges) for cycle in cycles: len_cycle = len(cycle) if len_cycle > k: cycle_vars = [vars[(cycle[i], cycle[(i+1) % len_cycle])] for i in range(len_cycle)] ones = [1.0]*len(cycle_vars) expr = LinExpr() expr.addTerms(ones, cycle_vars) model.cbLazy(expr <= len_cycle - 1) m.optimize(callback) m.update() c_edges = [e for e in edges if vars[e].x == 1.0] cycles = cycles_from_edges(c_edges) return cycles, m.objval
def two_cycle(A, C, gap): """ Solve high-vertex dense graphs by reduction to weighted matching ILP. """ _ = '*' m = Model() m.modelsense = GRB.MAXIMIZE m.params.mipgap = gap m.params.timelimit = 60 * 60 n = A.shape[0] vars = {} edges = tuplelist() # model as undirected graph for i in range(n): for j in range(i+1, n): if A[i, j] == 1 and A[j, i] == 1: e = (i, j) edges.append(e) w_i = 2 if i in C else 1 w_j = 2 if j in C else 1 w = w_i + w_j var = m.addVar(vtype=GRB.BINARY, obj=w) vars[e] = var m.update() # 2 cycle constraint <=> undirected flow <= 1 for i in range(n): lhs = LinExpr() lhs_vars = [vars[e] for e in chain(edges.select(i, _), edges.select(_, i))] ones = [1.0]*len(lhs_vars) lhs.addTerms(ones, lhs_vars) m.addConstr(lhs <= 1) m.optimize() m.update() cycles = [list(e) for e in edges if vars[e].x == 1.0] return cycles, m.objval
#!/usr/bin/env python # This is the GAP per Wolsey, pg 182, using Lagrangian Relaxation from gurobipy import GRB, Model model = Model('GAP per Wolsey with Lagrangian Relaxation') model.modelSense = GRB.MAXIMIZE model.setParam('OutputFlag', False) # turns off solver chatter b = [15, 15, 15] c = [ [ 6, 10, 1], [12, 12, 5], [15, 4, 3], [10, 3, 9], [ 8, 9, 5] ] a = [ [ 5, 7, 2], [14, 8, 7], [10, 6, 12], [ 8, 4, 15], [ 6, 12, 5] ] # x[i][j] = 1 if i is assigned to j x = [] for i in range(len(c)): x_i = [] for j in c[i]:
def build_model(data, n_cliques = 0, verbose = True): # Load Data Format n = data['n'] r = data['r'] p = data['p'] s = data['s'] c = data['c'] h = data['h'] w = data['w'] location = data['location'] conflicts = data['conflicts'] locking_times = data['locking_times'] T = data['T'] model = Model("ExaminationScheduling") if verbose: print("Building variables...") # x[i,k,l] = 1 if exam i is at time l in room k x = {} for k in range(r): for l in range(p): if T[k][l] == 1: for i in range(n): if location[k] in w[i]: x[i,k,l] = model.addVar(vtype=GRB.BINARY, name="x_%s_%s_%s" % (i,k,l)) # y[i,l] = 1 if exam i is at time l y = {} for i in range(n): for l in range(p): y[i, l] = model.addVar(vtype=GRB.BINARY, name="y_%s_%s" % (i,l)) # integrate new variables model.update() start = timeit.default_timer() # not very readable but same constraints as in GurbiLinear_v_10: speeded up model building by 2 for small problems (~400 exams) and more for huger problem ~1500 exams if verbose: print("Building constraints...") obj = LinExpr() sumconflicts = {} maxrooms = {} for i in range(n): sumconflicts[i] = sum(conflicts[i]) if s[i] <= 50: maxrooms[i] = 1 elif s[i] <= 100: maxrooms[i] = 2 elif s[i] <= 400: maxrooms[i] = 7 elif s[i] <= 700: maxrooms[i] = 9 else: maxrooms[i] = 12 c2 = LinExpr() c4 = LinExpr() for l in range(p): c1 = LinExpr() c1 = LinExpr() c3 = LinExpr() for k in range(r): if T[k][l] == 1 and location[k] in w[i]: c1.addTerms(1, x[i, k, l]) c4.addTerms(c[k],x[i,k,l]) obj += c1 model.addConstr(c1 <= maxrooms[i]* y[i,l], "c1a") model.addConstr(c1 >= y[i,l], "C1b") for j in conflicts[i]: c3.addTerms(1,y[j,l]) model.addConstr(c3 <= (1 - y[i,l])*sumconflicts[i], "c3") c2.addTerms(1,y[i,l]) model.addConstr( c2 == 1 , "c2") model.addConstr(c4 >= s[i], "c4") sumrooms = {} for l in range(p): sumrooms[l] = 0 cover_inequalities = LinExpr() for k in range(r): if T[k][l] == 1: sumrooms[l] += 1 c5 = LinExpr() for i in range(n): if location[k] in w[i]: c5.addTerms(1,x[i,k,l]) model.addConstr( c5 <= 1, "c5") cover_inequalities += c5 model.addConstr(cover_inequalities <= sumrooms[l], "cover_inequalities") model.setObjective( obj, GRB.MINIMIZE) print timeit.default_timer()-start if verbose: print("All constrained and objective built - OK") if not verbose: model.params.OutputFlag = 0 # Set Parameters #print("Setting Parameters...") # max presolve agressivity #model.params.presolve = 2 # Choosing root method 3= concurrent = run barrier and dual simplex in parallel #model.params.method = 1 #model.params.MIPFocus = 1 model.params.OutputFlag = 1 model.params.Method = 3 # cuts model.params.cuts = 0 model.params.cliqueCuts = 0 model.params.coverCuts = 0 model.params.flowCoverCuts = 0 model.params.FlowPathcuts = 0 model.params.GUBCoverCuts = 0 model.params.impliedCuts = 0 model.params.MIPSepCuts = 0 model.params.MIRCuts = 0 model.params.ModKCuts = 0 model.params.NetworkCuts = 2 model.params.SUBMIPCuts = 0 model.params.ZeroHalfCuts = 0 model.params.TimeLimit = 30 # # Tune the model # model.tune() # if model.tuneResultCount > 0: # # Load the best tuned parameters into the model # model.getTuneResult(0) # # Write tuned parameters to a file # model.write('tune1.prm') # return return(model)
def global_model(N, k_choices, distance_matrix): if k_choices >= N: raise ValueError("k_choices must be less than N") model = Model("distance1") I = range(N) distance_matrix = np.array( distance_matrix / distance_matrix.max(), dtype=np.float64) dm = distance_matrix ** 2 y, x = {}, {} for i in I: y[i] = model.addVar(vtype="B", obj=0, name="y[%s]" % i) for j in range(i + 1, N): x[i, j] = model.addVar( vtype="B", obj=1.0, name="x[%s,%s]" % (i, j)) model.update() model.setObjective(quicksum([x[i, j] * dm[j][i] for i in I for j in range(i + 1, N)])) # Add constraints to the model model.addConstr(quicksum([y[i] for i in I]) <= k_choices, "27") for i in I: for j in range(i + 1, N): model.addConstr(x[i, j] <= y[i], "28-%s-%s" % (i, j)) model.addConstr(x[i, j] <= y[j], "29-%s-%s" % (i, j)) model.addConstr(y[i] + y[j] <= 1 + x[i, j], "30-%s-%s" % (i, j)) model.addConstr(quicksum([x[i, j] for i in I for j in range(i + 1, N)]) <= nchoosek(k_choices, 2), "Cut_1") model.update() return model
def __loadModel(self): # Create optimization model self.__model = Model('Backup') # Auxiliary variables for SOCP reformulation U = {} R = {} # Create variables for i,j in self.__links: self.__BackupCapacity[i,j] = self.__model.addVar(lb=0, obj=1, name='Backup_Capacity[%s,%s]' % (i, j)) self.__model.update() for i,j in self.__links: for s,d in self.__links: self.__bBackupLink[i,j,s,d] = self.__model.addVar(vtype=GRB.BINARY,obj=1,name='Backup_Link[%s,%s,%s,%s]' % (i, j, s, d)) self.__model.update() for i,j in self.__links: U[i,j] = self.__model.addVar(obj=1,name='U[%s,%s]' % (i, j)) self.__model.update() for i,j in self.__links: for s,d in self.__links: R[i,j,s,d] = self.__model.addVar(obj=1,name='R[%s,%s,%s,%s]' % (i,j,s,d)) self.__model.update() self.__model.modelSense = GRB.MINIMIZE #m.setObjective(quicksum([fixedCosts[p]*open[p] for p in plants])) self.__model.setObjective(quicksum(self.__BackupCapacity[i,j] for i,j in self.__links)) self.__model.update() #------------------------------------------------------------------------# # Constraints definition # # # # # #------------------------------------------------------------------------# # Link capacity constraints for i,j in self.__links: self.__model.addConstr(self.__BackupCapacity[i,j] >= quicksum(self.__mean[s,d]*self.__bBackupLink[i,j,s,d] for (s,d) in self.__links) + U[i,j]*self.__invstd,'[CONST]Link_Cap_%s_%s' % (i, j)) self.__model.update() # SCOP Reformulation Constraints for i,j in self.__links: self.__model.addConstr(quicksum(R[i,j,s,d]*R[i,j,s,d] for (s,d) in self.__links) <= U[i,j]*U[i,j],'[CONST]SCOP1[%s][%s]' % (i, j)) self.__model.update() # SCOP Reformulation Constraints for i,j in self.__links: for s,d in self.__links: self.__model.addConstr(self.__std[s,d]*self.__bBackupLink[i,j,s,d] == R[i,j,s,d],'[CONST]SCOP2[%s][%s][%s][%s]' % (i, j,s,d)) self.__model.update() for i in self.__nodes: for s,d in self.__links: # Flow conservation constraints if i == s: self.__model.addConstr(quicksum(self.__bBackupLink[i,j,s,d] for i,j in self.__links.select(i,'*')) - quicksum(self.__bBackupLink[j,i,s,d] for j,i in self.__links.select('*',i)) == 1,'Flow1[%s,%s,%s,%s]' % (i,j,s, d)) # Flow conservation constraints elif i == d: self.__model.addConstr(quicksum(self.__bBackupLink[i,j,s,d] for i,j in self.__links.select(i,'*')) - quicksum(self.__bBackupLink[j,i,s,d] for j,i in self.__links.select('*',i)) == -1,'Flow2[%s,%s,%s,%s]' % (i,j,s, d)) # Flow conservation constraints else: self.__model.addConstr(quicksum(self.__bBackupLink[i,j,s,d] for i,j in self.__links.select(i,'*')) - quicksum(self.__bBackupLink[j,i,s,d] for j,i in self.__links.select('*',i)) == 0,'Flow3[%s,%s,%s,%s]' % (i,j,s, d)) self.__model.update()
def __optmize_single_project(self, x, j): ''' Given the generated x for single project, try to optimize the tardiness of the project. :param x: the assignment of resource supplier to project :param j: index of project :return: ''' m = Model("SingleProject_%d" % j) #### Create variables #### project = self.project_list[j] ## Project complete data,Project Tadeness,construction completion time CT = m.addVar(obj=0, vtype=GRB.CONTINUOUS, name="(CT%d)" % j) ## Activity start time ST = {} project_activities = self.project_activity[project] # print(project_activities.nodes()) for row in project_activities.nodes(): ST[row] = m.addVar(obj=0, vtype=GRB.CONTINUOUS, name="(ST%d,%s)" % (j, row)) ## Review sequence z_ij ## move to annealing objective function # y y = {} for activity_i in project_activities.nodes(): for activity_j in project_activities.nodes(): # print(project_activities.node[activity_i]) # print(dir(project_activities.node[activity_i])) if activity_i != activity_j and len(list( set(project_activities.node[activity_i]['rk_resources']).intersection( project_activities.node[activity_j]['rk_resources']))) > 0: y[activity_i, activity_j] = m.addVar(obj=0, vtype=GRB.BINARY, name="(y%d,%s,%s)" % (j, activity_i, activity_j)) m.update() #### Create constrains #### ## Constrain 2: project complete data>due data ## move to annealing objective function ## Constrain 3: supplier capacity limit ## move to annealing neighbor & random generator ## Constrain 4,6: project demand require; each project receive from one supplier for each resource ## move to annealing neighbor & random generator ## constrain 5: shipping constrain ## move to annealing neighbor & random generator ## Constrain 7:budget limit ## move to annealing constraint valid ## Constrain 8: activity starting constrain for a in project_activities.nodes(): for r in project_activities.node[a]['resources']: resource_delivered_days = 0 for s in self.resource_supplier_list[r]: resource_delivered_days += x.get((r, s, project), 0) * \ (self.resource_supplier_release_time[r, s] + self.supplier_project_shipping[ r, s, project]) m.addConstr(resource_delivered_days, GRB.LESS_EQUAL, ST[a], name="constraint_8_project_%d_activity_%s_resource_%s" % (j, a, r)) ## Constrain 9 activity sequence constrain for row1, row2 in project_activities.edges(): # print(row1, '#', row2, '#', j) # print(ST) m.addConstr(ST[row1] + project_activities.node[row1]['duration'], GRB.LESS_EQUAL, ST[row2], name="constraint_9_project_%d_activity_%s_activity_%s" % (j, row1, row2)) ## Constrain 10,11 for row1 in project_activities.nodes(): for row2 in project_activities.nodes(): if row1 != row2 and len(list( set(project_activities.node[row1]['rk_resources']).intersection( project_activities.node[row2]['rk_resources']))) > 0: m.addConstr(ST[row1] + project_activities.node[row1]['duration'] - self.M * ( 1 - y[row1, row2]), GRB.LESS_EQUAL, ST[row2], name="constraint_10_project_%d_activity_%s_activity_%s" % (j, row1, row2)) m.addConstr( ST[row2] + project_activities.node[row2]['duration'] - self.M * (y[row1, row2]), GRB.LESS_EQUAL, ST[row1], name="constraint_11_project_%d_activity_%s_activity_%s" % (j, row1, row2)) # m.addConstr(y[j,row1,row2]+y[j,row2,row1],GRB.LESS_EQUAL,1) ## Constrain 12 for row in project_activities.nodes(): # print(project_activities.node[row]['duration']) m.addConstr(CT, GRB.GREATER_EQUAL, ST[row] + project_activities.node[row]['duration'], name="constraint_12_project_%d_activity_%s" % (j, row)) ## Constrain 13 ## move to anealing objective function ## Constrain 14 ## move to anealing objective function ## Constrain 15 ## move to anealing objective function ## Constrain 16 ## move to anealing objective function ## Constrain 17 ## move to anealing objective function m.update() # Set optimization objective - minimize completion time expr = LinExpr() expr.add(CT) m.setObjective(expr, GRB.MINIMIZE) m.update() ########################################## m.params.presolve = 1 m.update() # Solve # m.params.presolve=0 m.optimize() m.write(join(self.output_dir, "heuristic_%d.lp" % j)) m.write(join(self.output_dir, "heuristic_%d.sol" % j)) return m.objVal
def LoadModel(self, Gamma, Nodes, Links, Capacity, Survivability, NumSamples): """ Load model. Parameters ---------- Gamma : importance sampling vector """ self.Links = tuplelist(Links) self.Capacity = Capacity # Create optimization model self.model = Model("Backup") # Create variables for i, j in self.Links: self.BackupCapacity[i, j] = self.model.addVar( vtype=GRB.CONTINUOUS, lb=0, name="Backup_Capacity[%s,%s]" % (i, j) ) # self.BackupCapacity[i,j] = self.model.addVar(lb=0, name='Backup_Capacity[%s,%s]' % (i, j)) self.model.update() for i, j in self.Links: for s, d in self.Links: self.bBackupLink[i, j, s, d] = self.model.addVar( vtype=GRB.BINARY, name="Backup_Link[%s,%s,%s,%s]" % (i, j, s, d) ) self.model.update() for i, j in self.Links: for k in range(NumSamples): self.z[k, i, j] = self.model.addVar(lb=0, name="z[%s][%s][%s]" % (k, i, j)) self.model.update() for i, j in self.Links: self.z0[i, j] = self.model.addVar(lb=-GRB.INFINITY, name="z0[%s][%s]" % (i, j)) self.model.update() self.model.modelSense = GRB.MINIMIZE self.model.setObjective(quicksum(self.BackupCapacity[i, j] for i, j in self.Links)) self.model.update() # ------------------------------------------------------------------------# # Constraints definition # # # # # # ------------------------------------------------------------------------# # Buffer probability I for i, j in self.Links: self.model.addConstr( self.z0[i, j] + 1 / (NumSamples * Survivability) * quicksum(self.z[k, i, j] for (k) in range(NumSamples)) <= 0, "[CONST]Buffer_Prob_I[%s][%s]" % (i, j), ) self.model.update() # Link capacity constraints for i, j in self.Links: for k in range(NumSamples): if Gamma == None: self.model.addConstr( ( quicksum(self.bBackupLink[i, j, s, d] * Capacity[k, s, d] for s, d in self.Links) - self.BackupCapacity[i, j] - self.z0[i, j] ) <= self.z[k, i, j], "[CONST]Buffer_Prob_II[%s][%s][%s]" % (k, i, j), ) else: self.model.addConstr( ( quicksum(self.bBackupLink[i, j, s, d] * Capacity[k, s, d] for s, d in self.Links) - self.BackupCapacity[i, j] - self.z0[i, j] ) * Gamma[k] <= self.z[k, i, j], "[CONST]Buffer_Prob_II[%s][%s][%s]" % (k, i, j), ) self.model.update() # Link capacity constraints for i, j in self.Links: for k in range(NumSamples): self.model.addConstr(self.z[k, i, j] >= 0, "[CONST]Buffer_Prob_III[%s][%s][%s]" % (k, i, j)) self.model.update() for i in Nodes: for s, d in self.Links: # Flow conservation constraints if i == s: self.model.addConstr( quicksum(self.bBackupLink[i, j, s, d] for i, j in self.Links.select(i, "*")) - quicksum(self.bBackupLink[j, i, s, d] for j, i in self.Links.select("*", i)) == 1, "Flow1[%s,%s,%s]" % (i, s, d), ) # Flow conservation constraints elif i == d: self.model.addConstr( quicksum(self.bBackupLink[i, j, s, d] for i, j in self.Links.select(i, "*")) - quicksum(self.bBackupLink[j, i, s, d] for j, i in self.Links.select("*", i)) == -1, "Flow2[%s,%s,%s]" % (i, s, d), ) # Flow conservation constraints else: self.model.addConstr( quicksum(self.bBackupLink[i, j, s, d] for i, j in self.Links.select(i, "*")) - quicksum(self.bBackupLink[j, i, s, d] for j, i in self.Links.select("*", i)) == 0, "Flow3[%s,%s,%s]" % (i, s, d), ) self.model.update()
class BFPBackupNetwork_Continuous(object): """ Class object for buffered failure probability-based model. Parameters ---------- Gamma: importance sampling vector Nodes: set of nodes Links: set of links Capacity: capacities per link based based on random failures Survivability: desired survivabiliy factor (epsilon) K: number of random scenarios Returns ------- BackupCapacity: set of capacity per backup link. BackupRoutes: set of backup links """ # Private model object model = [] # Private model variables BackupCapacity = {} bBackupLink = {} z0 = {} z = {} def __init__(self): """ Constructor """ def LoadModel(self, Gamma, Nodes, Links, Capacity, Survivability, NumSamples): """ Load model. Parameters ---------- Gamma : importance sampling vector """ self.Links = tuplelist(Links) self.Capacity = Capacity # Create optimization model self.model = Model("Backup") # Create variables for i, j in self.Links: self.BackupCapacity[i, j] = self.model.addVar( vtype=GRB.CONTINUOUS, lb=0, name="Backup_Capacity[%s,%s]" % (i, j) ) # self.BackupCapacity[i,j] = self.model.addVar(lb=0, name='Backup_Capacity[%s,%s]' % (i, j)) self.model.update() for i, j in self.Links: for s, d in self.Links: self.bBackupLink[i, j, s, d] = self.model.addVar( vtype=GRB.BINARY, name="Backup_Link[%s,%s,%s,%s]" % (i, j, s, d) ) self.model.update() for i, j in self.Links: for k in range(NumSamples): self.z[k, i, j] = self.model.addVar(lb=0, name="z[%s][%s][%s]" % (k, i, j)) self.model.update() for i, j in self.Links: self.z0[i, j] = self.model.addVar(lb=-GRB.INFINITY, name="z0[%s][%s]" % (i, j)) self.model.update() self.model.modelSense = GRB.MINIMIZE self.model.setObjective(quicksum(self.BackupCapacity[i, j] for i, j in self.Links)) self.model.update() # ------------------------------------------------------------------------# # Constraints definition # # # # # # ------------------------------------------------------------------------# # Buffer probability I for i, j in self.Links: self.model.addConstr( self.z0[i, j] + 1 / (NumSamples * Survivability) * quicksum(self.z[k, i, j] for (k) in range(NumSamples)) <= 0, "[CONST]Buffer_Prob_I[%s][%s]" % (i, j), ) self.model.update() # Link capacity constraints for i, j in self.Links: for k in range(NumSamples): if Gamma == None: self.model.addConstr( ( quicksum(self.bBackupLink[i, j, s, d] * Capacity[k, s, d] for s, d in self.Links) - self.BackupCapacity[i, j] - self.z0[i, j] ) <= self.z[k, i, j], "[CONST]Buffer_Prob_II[%s][%s][%s]" % (k, i, j), ) else: self.model.addConstr( ( quicksum(self.bBackupLink[i, j, s, d] * Capacity[k, s, d] for s, d in self.Links) - self.BackupCapacity[i, j] - self.z0[i, j] ) * Gamma[k] <= self.z[k, i, j], "[CONST]Buffer_Prob_II[%s][%s][%s]" % (k, i, j), ) self.model.update() # Link capacity constraints for i, j in self.Links: for k in range(NumSamples): self.model.addConstr(self.z[k, i, j] >= 0, "[CONST]Buffer_Prob_III[%s][%s][%s]" % (k, i, j)) self.model.update() for i in Nodes: for s, d in self.Links: # Flow conservation constraints if i == s: self.model.addConstr( quicksum(self.bBackupLink[i, j, s, d] for i, j in self.Links.select(i, "*")) - quicksum(self.bBackupLink[j, i, s, d] for j, i in self.Links.select("*", i)) == 1, "Flow1[%s,%s,%s]" % (i, s, d), ) # Flow conservation constraints elif i == d: self.model.addConstr( quicksum(self.bBackupLink[i, j, s, d] for i, j in self.Links.select(i, "*")) - quicksum(self.bBackupLink[j, i, s, d] for j, i in self.Links.select("*", i)) == -1, "Flow2[%s,%s,%s]" % (i, s, d), ) # Flow conservation constraints else: self.model.addConstr( quicksum(self.bBackupLink[i, j, s, d] for i, j in self.Links.select(i, "*")) - quicksum(self.bBackupLink[j, i, s, d] for j, i in self.Links.select("*", i)) == 0, "Flow3[%s,%s,%s]" % (i, s, d), ) self.model.update() def Optimize(self, MipGap=None, TimeLimit=None, LogLevel=None): """ Optimize the defined model. Parameters ---------- MipGap : desired gap TimeLimit : time limit LogLevel: log level 1 for printing all optimal variables and None otherwise Returns ------- BackupCapacity: The total capacity assigned per backup link BackupRoutes: The set of selected backup links A tuple list with all paths for edge (s,d) that uses (i,j). """ self.model.write("bpbackup.lp") if MipGap != None: self.model.params.MIPGap = MipGap if TimeLimit != None: self.model.params.timeLimit = TimeLimit # Compute optimal solution self.model.optimize() # Print solution if self.model.status == GRB.Status.OPTIMAL: if LogLevel == 1: for v in self.model.getVars(): print("%s %g" % (v.varName, v.x)) self.BackupCapacitySolution = self.model.getAttr("x", self.BackupCapacity) self.BackupRoutesSolution = self.model.getAttr("x", self.bBackupLink) self.BackupLinksSolution = {} self.HatBackupCapacity = {} for link in self.BackupCapacitySolution: if self.BackupCapacitySolution[link] < 1 and self.BackupCapacitySolution[link] > 0.001: self.HatBackupCapacity[link] = math.ceil(self.BackupCapacitySolution[link]) else: self.HatBackupCapacity[link] = math.floor(self.BackupCapacitySolution[link]) if self.HatBackupCapacity[link] > 0: if len(self.BackupLinksSolution) == 0: self.BackupLinksSolution = [link] else: self.BackupLinksSolution = self.BackupLinksSolution + [link] else: print("Optimal value not found!\n") self.BackupCapacitySolution = [] self.BackupRoutesSolution = {} self.BackupLinksSolution = {} return self.BackupCapacitySolution, self.BackupRoutesSolution, self.BackupLinksSolution, self.HatBackupCapacity def SaveBakupNetwork(self, file_name): """Save the optimal backup network to the file ``file_name``.""" data = { "links": [i for i in self.BackupCapacitySolution], "capacities": [self.BackupCapacitySolution[i] for i in self.BackupCapacitySolution], "routes": [i for i in self.BackupRoutesSolution], "status": [self.BackupRoutesSolution[i] for i in self.BackupRoutesSolution], } f = open(file_name, "w") json.dump(data, f) f.close() def LoadBackupNetwork(self, file_name): """Load a backup network from the file ``file_name``. Returns the backup network solution saved in the file. """ f = open(file_name, "r") data = json.load(f) f.close() self.BackupCapacitySolution = {} self.BackupRoutesSolution = {} self.BackupLinksSolution = {} links = [i for i in data["links"]] capacities = [i for i in data["capacities"]] routes = [i for i in data["routes"]] status = [i for i in data["status"]] IndexAux = 0 for i, j in links: self.BackupCapacitySolution[i, j] = capacities[IndexAux] IndexAux = IndexAux + 1 self.HatBackupCapacity = {} for link in self.BackupCapacitySolution: if self.BackupCapacitySolution[link] < 1 and self.BackupCapacitySolution[link] > 0.001: self.HatBackupCapacity[link] = math.ceil(self.BackupCapacitySolution[link]) else: self.HatBackupCapacity[link] = math.floor(self.BackupCapacitySolution[link]) if self.HatBackupCapacity[link] > 0: if len(self.BackupLinksSolution) == 0: self.BackupLinksSolution = [link] else: self.BackupLinksSolution = self.BackupLinksSolution + [link] IndexAux = 0 for i, j, s, d in routes: self.BackupRoutesSolution[i, j, s, d] = status[IndexAux] IndexAux = IndexAux + 1 return self.BackupCapacitySolution, self.BackupRoutesSolution, self.BackupLinksSolution, self.HatBackupCapacity def ResetModel(self): """ Reset model solution. """ self.BackupCapacity = {} self.bBackupLink = {} self.z0 = {} self.z = {} if self.model: self.model.reset()
class SolveSC1GuMIP: """ Solve the initial marking problem optimally using Guroby (it must be install). The computation time can be quite long for big instances. """ def __init__(self, dataflow, verbose, lp_filename): """ Constructor """ self.dataflow = dataflow self.verbose = verbose self.lp_filename = lp_filename self.col_v = {} # dict use for storing gamma's variable column self.col_m0 = {} # dict use for storing bds's variable column self.col_fm0 = {} # dict use for storing FM0's variable column def compute_initial_marking(self): """launch the computation. This function return the objective value of the MILP problem The initial marking of the graph in parameter is modify. """ self.__init_prob() # Modify parameters self.__create_col() # Add Col on prob self.__create_row() # Add Row (constraint) on prob self.__create_obj() # Add objectif function self.__solve_prob() # Launch the solver and set preload of the graph del self.prob # Del prob return self.Z # Return the total amount find by the solver def __init_prob(self): # Modify parameters logging.info("Generating initial marking problem") self.prob = Model("SC1_MIP") # Gurobi parameters: if not self.verbose: self.prob.params.OutputFlag = 0 try: os.remove("gurobi.log") except OSError: pass self.prob.params.Threads = 2 self.prob.params.intfeastol = 0.000001 def __create_col(self): # Add Col on prob # Create column bds (M0) for arc in self.dataflow.get_arc_list(): self.__add_col_m0(arc) # Create column bds (FM0) for arc in self.dataflow.get_arc_list(): self.__add_col_fm0(arc) # Create column lambda (v) for task in self.dataflow.get_task_list(): phase_count = self.__get_range_phases(task) for i in xrange(phase_count): self.__add_col_v(str(task) + "/" + str(i)) # Integrate new variables self.prob.update() def __create_row(self): # Add Row (constraint) on prob # BEGUIN FILL ROW ######################################################################## # Constraint FM0*step - M0 = 0 # ######################################################################## for arc in self.dataflow.get_arc_list(): if not self.dataflow.is_arc_reentrant(arc): arc_gcd = self.dataflow.get_gcd(arc) self.__add_frow(arc, arc_gcd) ######################################################################## # Constraint u-u'+M0 >= W1+1 # ######################################################################## for arc in self.dataflow.get_arc_list(): source = self.dataflow.get_source(arc) target = self.dataflow.get_target(arc) if not self.dataflow.is_arc_reentrant(arc): range_source = self.__get_range_phases(source) range_target = self.__get_range_phases(target) prod_list = self.__get_prod_rate_list(arc) cons_list = self.__get_cons_rate_list(arc) if self.dataflow.is_pcg: threshold_list = self.__get_threshold_list(arc) arc_gcd = self.dataflow.get_gcd(arc) pred_prod = 0 for sourcePhase in xrange(range_source): # source/prod/out normaux if sourcePhase > 0: pred_prod += prod_list[sourcePhase - 1] pred_cons = 0 cons = 0 for targetPhase in xrange(range_target): # target/cons/in normaux cons += cons_list[targetPhase] if targetPhase > 0: pred_cons += cons_list[targetPhase - 1] w = cons - pred_prod - arc_gcd if self.dataflow.is_pcg: w += pred_cons + threshold_list[targetPhase] - cons str_v1 = str(source) + "/" + str(sourcePhase) str_v2 = str(target) + "/" + str(targetPhase) self.__add_row(str_v1, str_v2, arc, w) # END FILL ROW def __create_obj(self): obj = QuadExpr() for arc in self.dataflow.get_arc_list(): obj += self.col_m0[arc] self.prob.setObjective(obj, GRB.MINIMIZE) def __solve_prob(self): # Launch the solver and set preload of the graph logging.info("loading matrix ...") self.prob.update() if self.lp_filename is not None: problem_location = str(self.prob.write(self.lp_filename)) logging.info("Writing problem: " + str(problem_location)) logging.info("solving problem ...") self.prob.optimize() logging.info("Integer solving done !") self.Z = self.prob.objVal for arc in self.dataflow.get_arc_list(): if not self.dataflow.is_arc_reentrant(arc): self.dataflow.set_initial_marking(arc, int(self.col_m0[arc].x)) logging.info("SC1 MIP Mem tot (no reentrant): " + str(self.Z)) # Add a variable lamda def __add_col_v(self, name): var = self.prob.addVar(vtype=GRB.CONTINUOUS, name=name) self.col_v[name] = var # Add a variable M0 def __add_col_m0(self, arc): var = self.prob.addVar(lb=0, vtype=GRB.INTEGER) self.col_m0[arc] = var # Add a variable FM0 def __add_col_fm0(self, arc): var = self.prob.addVar(lb=0, vtype=GRB.INTEGER) self.col_fm0[arc] = var # Add a constraint: lambda1 - lambda2 + M0 > W1 def __add_row(self, str_v1, str_v2, arc, w): expr = LinExpr() if not self.dataflow.is_arc_reentrant(arc): expr += self.col_v[str_v1] expr -= self.col_v[str_v2] expr += self.col_m0[arc] self.prob.addConstr(expr, GRB.GREATER_EQUAL, w + 0.00001) # Add a constraint: FM0*step = M0 def __add_frow(self, arc, step): expr = LinExpr() expr += self.col_fm0[arc]*float(step) expr -= self.col_m0[arc] self.prob.addConstr(expr, GRB.EQUAL, 0) def __get_range_phases(self, task): if self.dataflow.is_sdf: return 1 range_task = self.dataflow.get_phase_count(task) if self.dataflow.is_pcg: range_task += self.dataflow.get_ini_phase_count(task) return range_task def __get_prod_rate_list(self, arc): if self.dataflow.is_sdf: return [self.dataflow.get_prod_rate(arc)] prod_list = self.dataflow.get_prod_rate_list(arc) if self.dataflow.is_pcg: prod_list = self.dataflow.get_ini_prod_rate_list(arc) + prod_list return prod_list def __get_cons_rate_list(self, arc): if self.dataflow.is_sdf: return [self.dataflow.get_cons_rate(arc)] cons_list = self.dataflow.get_cons_rate_list(arc) if self.dataflow.is_pcg: cons_list = self.dataflow.get_ini_cons_rate_list(arc) + cons_list return cons_list def __get_threshold_list(self, arc): return self.dataflow.get_ini_threshold_list(arc) + self.dataflow.get_threshold_list(arc)
def _initialize_model(self): problem = Model() problem.setParam('OutputFlag', False) # edges from source to reviewers, capacity controls maximum reviewer load self._source_vars = problem.addVars(self.numrev, vtype=GRB.CONTINUOUS, lb=0.0, ub=self.ability, name='reviewers') # edges from papers to sink, capacity controls a number of reviewers per paper self._sink_vars = problem.addVars(self.numpapers, vtype=GRB.CONTINUOUS, lb=0.0, ub=self.demand, name='papers') # edges between reviewers and papers. Initially capacities are set to 0 (no edge is added in the network) self._mix_vars = problem.addVars(self.numrev, self.numpapers, vtype=GRB.CONTINUOUS, lb=0.0, ub=0.0, name='assignment') problem.update() # flow balance equations for reviewers' nodes self._balance_reviewers = problem.addConstrs((self._source_vars[i] == self._mix_vars.sum(i, '*') for i in range(self.numrev))) # flow balance equations for papers' nodes self._balance_papers = problem.addConstrs((self._sink_vars[i] == self._mix_vars.sum('*', i) for i in range(self.numpapers))) problem.update() self._problem = problem
def __init__(self): Solver.__init__(self) self.problem = GurobiModel()
def build_model(data, n_cliques = 0, verbose = True): # Load Data Format n = data['n'] r = data['r'] p = data['p'] s = data['s'] c = data['c'] h = data['h'] w = data['w'] location = data['location'] conflicts = data['conflicts'] locking_times = data['locking_times'] T = data['T'] model = Model("ExaminationScheduling") if verbose: print("Building variables...") # x[i,k,l] = 1 if exam i is at time l in room k x = {} for k in range(r): for l in range(p): if T[k][l] == 1: for i in range(n): if location[k] in w[i]: x[i,k,l] = model.addVar(vtype=GRB.BINARY, name="x_%s_%s_%s" % (i,k,l)) # y[i,l] = 1 if exam i is at time l y = {} for i in range(n): for l in range(p): y[i, l] = model.addVar(vtype=GRB.BINARY, name="y_%s_%s" % (i,l)) # integrate new variables model.update() start = timeit.default_timer() # adding constraints as found in MidTerm.pdf if verbose: print("Building constraints...") if verbose: print("c1: connecting variables x and y") for i in range(n): for l in range(p): model.addConstr( quicksum([ x[i, k, l] for k in range(r) if T[k][l] == 1 and location[k] in w[i] ]) <= 12 * y[i, l], "c1a") model.addConstr( quicksum([ x[i, k, l] for k in range(r) if T[k][l] == 1 and location[k] in w[i] ]) >= y[i, l], "c1b") if verbose: print("c2: each exam at exactly one time") for i in range(n): model.addConstr( quicksum([ y[i, l] for l in range(p) ]) == 1 , "c2") """ Idea: -instead of saving a conflict Matrix, save Cliques of exams that cannot be written at the same time -then instead of saying of one exam is written in a given period all conflicts cannot be written in the same period we could say -for all exams in a given clique only one can be written """ if verbose: print("c3: avoid conflicts") for i in range(n): for l in range(p): # careful!! Big M changed! model.addConstr(quicksum([ y[j,l] for j in conflicts[i] ]) <= (1 - y[i, l]) * sum(conflicts[i]), "c3") if verbose: print("c4: seats for all students") for i in range(n): model.addConstr( quicksum([ x[i, k, l] * c[k] for k in range(r) for l in range(p) if T[k][l] == 1 and location[k] in w[i] ]) >= s[i], "c4") if verbose: print("c5: only one exam per room per period") for k in range(r): for l in range(p): if T[k][l] == 1: model.addConstr( quicksum([ x[i, k, l] for i in range(n) if location[k] in w[i] ]) <= 1, "c5") if verbose: print("All constrained built - OK") # objective: minimize number of used rooms if verbose: print("Building Objective...") obj1 = quicksum([ x[i,k,l] for i,k,l in itertools.product(range(n), range(r), range(p)) if T[k][l] == 1 and location[k] in w[i]]) model.setObjective( obj1, GRB.MINIMIZE) print timeit.default_timer()-start if not verbose: model.params.OutputFlag = 0 # Set Parameters #print("Setting Parameters...") # max presolve agressivity #model.params.presolve = 2 # Choosing root method 3= concurrent = run barrier and dual simplex in parallel #model.params.method = 1 #model.params.MIPFocus = 1 #model.params.cuts = 0 model.params.OutputFlag = 1 # # Tune the model # model.tune() # if model.tuneResultCount > 0: # # Load the best tuned parameters into the model # model.getTuneResult(0) # # Write tuned parameters to a file # model.write('tune1.prm') # return return(model)
def ilp(costMatrix): #Invalid_Connections : -1 if costMatrix.shape==(0,0): return [] dist_mat=numpy.copy(costMatrix) dist_mat[costMatrix==-1]=10e10 size_x = dist_mat.shape[0] size_y = dist_mat.shape[1] size_min = int(numpy.amin([size_x,size_y])) from gurobipy import Model, quicksum, GRB m=Model("mip1") COS,VAR={},{} for i in range(size_x): x_cos, x_var = [],[] for j in range(size_y): COS[i,j]=dist_mat[i,j] VAR[i,j]=m.addVar(vtype='B',name="["+str(i)+","+str(j)+"]") m.update() # Set objective m.setObjective( quicksum(\ COS[x,y]*VAR[x,y] for x in range(size_x) \ for y in range(size_y) \ ),GRB.MINIMIZE) # Constrains HORIZONTAL for i in range(size_x): m.addConstr( quicksum\ (VAR[i,y] for y in range(size_y)) <= 1) # Constrains VERTICAL for i in range(size_y): m.addConstr( quicksum\ (VAR[x,i] for x in range(size_x)) <= 1) m.addConstr(quicksum(\ VAR[x,y] for x in range(size_x) for y in range(size_y)) == int(size_min)) m.setParam("OutputFlag",False) m.optimize() res=numpy.zeros(dist_mat.shape,dtype=bool) for i in range(size_x): for j in range(size_y): res[i,j]=VAR[i,j].x binMatrix = numpy.zeros( costMatrix.shape,dtype=bool ) binMatrix[res==1]=1 binMatrix[costMatrix==-1]=0 return binMatrix
def tsp_gurobi(edges): """ Modeled using GUROBI python example. """ from gurobipy import Model, GRB, quicksum edges = populate_edge_weights(edges) incoming, outgoing, nodes = node_to_edge(edges) idx = dict((n, i) for i, n in enumerate(nodes)) nedges = len(edges) n = len(nodes) m = Model() step = lambda x: "u_{0}".format(x) # Create variables vars = {} for i, (a, b, w) in enumerate(edges): vars[i] = m.addVar(obj=w, vtype=GRB.BINARY, name=str(i)) for u in nodes[1:]: u = step(u) vars[u] = m.addVar(obj=0, vtype=GRB.INTEGER, name=u) m.update() # Bounds for step variables for u in nodes[1:]: u = step(u) vars[u].lb = 1 vars[u].ub = n - 1 # Add degree constraint for v in nodes: incoming_edges = incoming[v] outgoing_edges = outgoing[v] m.addConstr(quicksum(vars[x] for x in incoming_edges) == 1) m.addConstr(quicksum(vars[x] for x in outgoing_edges) == 1) # Subtour elimination edge_store = dict(((idx[a], idx[b]), i) for i, (a, b, w) in enumerate(edges)) # Given a list of edges, finds the shortest subtour def subtour(s_edges): visited = [False] * n cycles = [] lengths = [] selected = [[] for i in range(n)] for x, y in s_edges: selected[x].append(y) while True: current = visited.index(False) thiscycle = [current] while True: visited[current] = True neighbors = [x for x in selected[current] if not visited[x]] if len(neighbors) == 0: break current = neighbors[0] thiscycle.append(current) cycles.append(thiscycle) lengths.append(len(thiscycle)) if sum(lengths) == n: break return cycles[lengths.index(min(lengths))] def subtourelim(model, where): if where != GRB.callback.MIPSOL: return selected = [] # make a list of edges selected in the solution sol = model.cbGetSolution([model._vars[i] for i in range(nedges)]) selected = [edges[i] for i, x in enumerate(sol) if x > .5] selected = [(idx[a], idx[b]) for a, b, w in selected] # find the shortest cycle in the selected edge list tour = subtour(selected) if len(tour) == n: return # add a subtour elimination constraint c = tour incident = [edge_store[a, b] for a, b in pairwise(c + [c[0]])] model.cbLazy(quicksum(model._vars[x] for x in incident) <= len(tour) - 1) m.update() m._vars = vars m.params.LazyConstraints = 1 m.optimize(subtourelim) selected = [v.varName for v in m.getVars() if v.x > .5] selected = [int(x) for x in selected if x[:2] != "u_"] results = sorted(x for i, x in enumerate(edges) if i in selected) \ if selected else None return results
def run_algorithm(self): old_M = self.M old_items = [i.copy() for i in self.items] map_name_to_old_item = dict() for i in old_items: map_name_to_old_item[i.name] = i self.scale_items_by_cost() from gurobipy import Model, GRB model = Model("NP-Hard") print("Setting Model Parameters") # set timeout model.setParam('TimeLimit', 1600) model.setParam('MIPFocus', 3) model.setParam('PrePasses', 1) model.setParam('Heuristics', 0.01) model.setParam('Method', 0) map_name_to_item = dict() map_name_to_cost = dict() map_name_to_weight = dict() map_name_to_profit = dict() map_class_to_name = dict() item_names = list() print("Preprocessing data for model...") for item in self.items: item_names.append(item.name) map_name_to_item[item.name] = item map_name_to_cost[item.name] = item.cost map_name_to_weight[item.name] = item.weight map_name_to_profit[item.name] = item.profit if item.classNumber not in map_class_to_name: map_class_to_name[item.classNumber] = list() map_class_to_name[item.classNumber].append(item.name) class_numbers = list(map_class_to_name.keys()) print("Setting model variables...") # binary variables =1, if use>0 items = model.addVars(item_names, vtype=GRB.BINARY, name="items") classes = model.addVars(class_numbers, vtype=GRB.BINARY, name="class numbers") print("Setting model objective...") # maximize profit objective = items.prod(map_name_to_profit) model.setObjective(objective, GRB.MAXIMIZE) # constraints print("Setting model constraints") model.addConstr(items.prod(map_name_to_weight) <= self.P,"weight capacity") model.addConstr(items.prod(map_name_to_cost) <= self.M,"cost capacity") # if any item from a class is chosen, that class variable has to be a binary of 1 for num in class_numbers: model.addGenConstrOr(classes[num], [items[x] for x in map_class_to_name[num]] ,name="class count") for c in self.raw_constraints: count = model.addVar() for n in c: if n in classes: count += classes[n] model.addConstr(count <= 1, name="constraint") print("Start optimizing...") model.optimize() print("Done! ") # Status checking status = model.Status if status == GRB.Status.INF_OR_UNBD or \ status == GRB.Status.INFEASIBLE or \ status == GRB.Status.UNBOUNDED: print('The model cannot be solved because it is infeasible or unbounded') if status != GRB.Status.OPTIMAL: print('Optimization was stopped with status ' + str(status)) Problem = True try: model.write("mps_model/" + self.filename + ".sol") except Exception as e: pass print("Generating solution file...") # Display solution solution_names = list() for i, v in enumerate(items): try: if items[v].X > 0.9: solution_names.append(item_names[i]) except Exception as e: pass self.M = old_M self.items = old_items solution = [map_name_to_old_item[i] for i in solution_names] return solution