def TSP(C): # Number of places n, n = C.shape # Create concrete model model = ConcreteModel() # Set of indices model.I = RangeSet(1, n) model.J = RangeSet(1, n) # Variables model.X = Var(model.I, model.J, within=Binary) model.U = Var(model.I, within=PositiveReals) # Objective Function model.obj = Objective(expr=sum(C[i - 1, j - 1] * model.X[i, j] for i, j in model.X)) # Constraints on the marginals model.InDegree = Constraint(model.I, rule=lambda m, i: sum(m.X[i, j] for j in m.J) == 1) model.OutDegree = Constraint(model.J, rule=lambda m, j: sum(m.X[i, j] for i in m.I) == 1) model.onedir = ConstraintList() for i in model.I: for j in model.J: model.onedir.add(expr=model.X[i, j] + model.X[j, i] <= 1) # # Subtour model.subtour = ConstraintList() for i in model.I: for j in model.J: if i > 1 and j > 1 and i != j: model.subtour.add( model.U[i] - model.U[j] + n * model.X[i, j] <= n - 1) model.fix = Constraint(expr=model.U[1] == 1) # Solve the model sol = SolverFactory('gurobi').solve(model, tee=True) # CHECK SOLUTION STATUS # Get a JSON representation of the solution sol_json = sol.json_repn() # Check solution status if sol_json['Solver'][0]['Status'] != 'ok': return None if sol_json['Solver'][0]['Termination condition'] != 'optimal': return None return [(i - 1, j - 1) for i, j in model.X if model.X[i, j]() > 0.5]
def build(self, lower, expr, upper): # Collect uncertain parameter and uncertainty set self.lower = lower self.upper = upper self._uncparam = _collect_uncparam(expr) self._uncset = [self._uncparam[0]._uncset] self._rule = self.construct_rule(expr) self._bounds = (lower, upper) # Generate nominal constraint nominal_expr = self.nominal_constraint_expr() self._constraints = ConstraintList() self._constraints.add(nominal_expr)
def test_rule_option3(self): model = self.create_model() model.y = Var(initialize=2) def f(model): yield model.y <= 0 yield 2*model.y <= 0 yield 2*model.y <= 0 yield ConstraintList.End model.c = ConstraintList(rule=f) self.assertEqual(len(model.c), 3) self.assertEqual(model.c[1](), 2) model.d = ConstraintList(rule=f(model)) self.assertEqual(len(model.d), 3) self.assertEqual(model.d[1](), 2)
def coefsFonRiProblem(Z, R, t, h): def objfun(m): s = 0 for i in range(1, len(R) + 1): s += m.nu[i] return 1 / 4 * integrate_onRi(m.nu, R, Z, h) + m.nu[0] * t + 1 / len(R) * (s) model = ConcreteModel() if len(R) != len(Z): raise Exception() model.I = RangeSet(0, len(R)) model.nu = Var(model.I, within=NonNegativeReals) # Vincoli model.nonNegDen = ConstraintList() for i in range(len(R)): for point in R[i]: model.nonNegDen.add( expr=model.nu[0] * norm(point - Z[i]) + model.nu[i + 1] >= 0) model.obj = Objective(rule=objfun) opt = SolverFactory('ipopt') opt.solve(model) return model
def test_rule_option4(self): model = self.create_model() model.y = Var(initialize=2) model.c = ConstraintList(rule=((i + 1) * model.y >= 0 for i in range(3))) self.assertEqual(len(model.c), 3) self.assertEqual(model.c[1](), 2)
def test_stats3(self): model = ConcreteModel() model.x = Var([1, 2]) def obj_rule(model, i): return sum_product(model.x) model.obj = Objective([1, 2], rule=obj_rule) def c_rule(model, i): expr = 0 for j in [1, 2]: expr += j * model.x[j] return expr == 0 model.c = Constraint([1, 2], rule=c_rule) # model.B = Block() model.B.x = Var([1, 2]) model.B.o = ObjectiveList() model.B.o.add(model.B.x[1]) model.B.o.add(model.B.x[2]) model.B.c = ConstraintList() model.B.c.add(model.x[1] == 0) model.B.c.add(model.x[2] == 0) self.assertEqual(model.nvariables(), 4) self.assertEqual(model.nobjectives(), 4) self.assertEqual(model.nconstraints(), 4)
def construct_separation_problem(self, sense=maximize): m = ConcreteModel() uncparam = self._uncparam[0] index = uncparam.index_set() # Create inner problem variables # TODO: use setattr to give uncparam same name as in model m.uncparam = Var(index) # collect current coefficient values expr = self._rule(m.uncparam, compute_values=True) # construct objective with current coefficient values m.obj = Objective(expr=expr, sense=sense) # construct constraints from uncertainty set uncset = self._uncset[0] m.cons = ConstraintList() substitution_map = {id(uncparam[i]): m.uncparam[i] for i in index} if not uncset.is_lib(): for c in uncset.component_data_objects(Constraint): m.cons.add( (c.lower, replace_expressions(c.body, substitution_map), c.upper)) else: for cons in uncset.generate_cons_from_lib(m.uncparam): m.cons.add(cons) return m
def test_induced_linearity_case2(self): m = ConcreteModel() m.x = Var([0], bounds=(-3, 8)) m.y = Var(RangeSet(4), domain=Binary) m.z = Var(domain=Integers, bounds=(-1, 2)) m.constr = Constraint( expr=m.x[0] == m.y[1] + 2 * m.y[2] + m.y[3] + 2 * m.y[4] + m.z) m.logical = ConstraintList() m.logical.add(expr=m.y[1] + m.y[2] == 1) m.logical.add(expr=m.y[3] + m.y[4] == 1) m.logical.add(expr=m.y[2] + m.y[4] <= 1) m.b = Var(bounds=(-2, 7)) m.c = Var() m.bilinear = Constraint( expr=(m.x[0] - 3) * (m.b + 2) - (m.c + 4) * m.b + exp(m.b ** 2) * m.x[0] <= m.c) TransformationFactory('contrib.induced_linearity').apply_to(m) xfrmed_blk = m._induced_linearity_info.x0_b_bilinear self.assertSetEqual( set(xfrmed_blk.valid_values), set([1, 2, 3, 4, 5])) select_one_repn = generate_standard_repn( xfrmed_blk.select_one_value.body) self.assertEqual( ComponentSet(select_one_repn.linear_vars), ComponentSet(xfrmed_blk.x_active[i] for i in xfrmed_blk.valid_values))
def test_bilinear_in_disjuncts(self): m = ConcreteModel() m.x = Var([0], bounds=(-3, 8)) m.y = Var(RangeSet(4), domain=Binary) m.z = Var(domain=Integers, bounds=(-1, 2)) m.constr = Constraint(expr=m.x[0] == m.y[1] + 2 * m.y[2] + m.y[3] + 2 * m.y[4] + m.z) m.logical = ConstraintList() m.logical.add(expr=m.y[1] + m.y[2] == 1) m.logical.add(expr=m.y[3] + m.y[4] == 1) m.logical.add(expr=m.y[2] + m.y[4] <= 1) m.v = Var([1, 2]) m.v[1].setlb(-2) m.v[1].setub(7) m.v[2].setlb(-4) m.v[2].setub(5) m.bilinear = Constraint( expr=(m.x[0] - 3) * (m.v[1] + 2) - (m.v[2] + 4) * m.v[1] + exp(m.v[1]**2) * m.x[0] <= m.v[2]) m.disjctn = Disjunction( expr=[[m.x[0] * m.v[1] <= 4], [m.x[0] * m.v[2] >= 6]]) TransformationFactory('contrib.induced_linearity').apply_to(m) self.assertEqual( m.disjctn.disjuncts[0].constraint[1].body.polynomial_degree(), 1) self.assertEqual( m.disjctn.disjuncts[1].constraint[1].body.polynomial_degree(), 1)
def test_expr5(self): model = ConcreteModel() model.A = Set(initialize=[1, 2, 3], doc='set A') model.B = Param(model.A, initialize={ 1: 100, 2: 200, 3: 300 }, doc='param B', mutable=True) model.C = Param(initialize=3, doc='param C', mutable=True) model.x = Var(model.A, doc='var x') model.y = Var(doc='var y') model.o = Objective(expr=model.y, doc='obj o') model.c1 = Constraint(expr=model.x[1] >= 0, doc='con c1') def c2_rule(model, a): return model.B[a] * model.x[a] <= 1 model.c2 = Constraint(model.A, doc='con c2', rule=c2_rule) model.c3 = ConstraintList(doc='con c3') model.c3.add(model.y <= 0) # OUTPUT = open(join(currdir, "test_expr5.out"), "w") model.pprint(ostream=OUTPUT) OUTPUT.close() _out, _txt = join(currdir, "test_expr5.out"), join(currdir, "test_expr5.txt") self.assertTrue(cmp(_out, _txt), msg="Files %s and %s differ" % (_out, _txt))
def build_mip(self): """Get an Abstract model and create a Concrete model with input data.""" self.model = self.create_abstract_model() build_info, indices = self._get_mip_build_info() if not self._apriori_infeasible: self._mip_indices = indices self._mip = self.model.create_instance(build_info) self._mip.extra_c = ConstraintList()
def test_fixed_var_out_of_bounds_ub(self): m = ConcreteModel() m.s = RangeSet(2) m.v = Var(m.s, bounds=(0, 5)) m.c = ConstraintList() m.c.add(expr=m.v[1] == m.v[2]) m.c.add(expr=m.v[1] == 6) with self.assertRaises(ValueError): TransformationFactory('contrib.aggregate_vars').apply_to(m)
def _add_data_block(self, existing_block=None): # If a sensitivity block already exists, and we have not done # any expression replacement, we delete the old block, re-fix the # sensitivity variables, and start again. # # Don't do this in the constructor as we could want to call # the constructor once, then perform multiple sensitivity # calculations with the same model instance. if existing_block is not None: if (hasattr(existing_block, '_has_replaced_expressions') and not existing_block._has_replaced_expressions): for var, _, _, _ in existing_block._sens_data_list: # Re-fix variables that the previous block was # treating as parameters. var.fix() self.model_instance.del_component(existing_block) else: msg = ("Re-using sensitivity interface is not supported " "when calculating sensitivity for mutable parameters. " "Used fixed vars instead if you want to do this." ) raise RuntimeError(msg) # Add a block to keep track of model components necessary for this # sensitivity calculation. block = Block() self.model_instance.add_component(self.get_default_block_name(), block) self.block = block # If the user tells us they will perturb a set of parameters, we will # need to replace these parameters in the user's model's constraints. # This affects what we can do with the model later, so we add a flag. block._has_replaced_expressions = False # This is the main data structure for keeping track of "sensitivity # vars" and their associated params. It will be a list of tuples of # (vardata, paramdata, list_index, comp_index) # where: # vardata is the "sensitivity variable" data object, # paramdata is the associated parameter, # list_index is its index in the user-provided list, and # comp_index is its index in the component provided by the user. block._sens_data_list = [] # This will hold the user-provided list of # variables and/or parameters to perturb block._paramList = None # This will hold any constraints where we have replaced # parameters with vairables. block.constList = ConstraintList() return block
def setup_sensitivity(self, paramList): """ """ instance = self.model_instance paramList = self._process_param_list(paramList) existing_block = instance.component(self.get_default_block_name()) block = self._add_data_block(existing_block=existing_block) block._sens_data_list = [] block._paramList = paramList self._add_sensitivity_data(paramList) sens_data_list = block._sens_data_list for var, _, _, _ in sens_data_list: # This unfixes all variables, not just those the user added. var.unfix() # Map used to replace user-provided parameters. variableSubMap = dict((id(param), var) for var, param, list_idx, _ in sens_data_list if paramList[list_idx].ctype is Param) if variableSubMap: # We now replace the provided parameters in the user's # expressions. Only do this if we have to, i.e. the # user provided some parameters rather than all vars. block._replaced_map = \ self._replace_parameters_in_constraints(variableSubMap) # Assume that we just replaced some params block._has_replaced_expressions = True block.paramConst = ConstraintList() for var, param, _, _ in sens_data_list: #block.paramConst.add(param - var == 0) block.paramConst.add(var - param == 0) # Declare Suffixes _add_sensitivity_suffixes(instance) for i, (var, _, _, _) in enumerate(sens_data_list): idx = i + 1 con = block.paramConst[idx] # sipopt instance.sens_state_0[var] = idx instance.sens_state_1[var] = idx instance.sens_init_constr[con] = idx # k_aug instance.dcdp[con] = idx
def test_conlist_skip(self): model = ConcreteModel() model.x = Var() model.c = ConstraintList() self.assertTrue(1 not in model.c) self.assertEqual(len(model.c), 0) model.c.add(Constraint.Skip) self.assertTrue(1 not in model.c) self.assertEqual(len(model.c), 0) model.c.add(model.x >= 1) self.assertTrue(1 not in model.c) self.assertTrue(2 in model.c) self.assertEqual(len(model.c), 1)
def Knapsack(): tools = ['hammer', 'wrench', 'screwdriver', 'towel'] v = {'hammer': 8, 'wrench': 3, 'screwdriver': 6, 'towel': 11} w = {'hammer': 5, 'wrench': 7, 'screwdriver': 4, 'towel': 3} limit = 14 M = ConcreteModel() M.ITEMS = Set(initialize=v.keys()) M.x = Var(M.ITEMS, within=Binary) # Define Uncertainty set & uncertain parameters mu = [w[t] for t in tools] A = [[0.1, 0.01, 0.0, 0.0], [0.01, 0.1, 0.0, 0.0], [0.0, 0.0, 0.1, 0.0], [0.0, 0.0, 0.0, 0.1]] Sig = np.linalg.inv(A).tolist() perm = itertools.product([1, -1], repeat=len(tools)) P = [i for i in perm] rhs = [sum(p[i] * w[t] for i, t in enumerate(tools)) + 5.5 for p in P] M.E = UncSet() M.w = UncParam(M.ITEMS, uncset=M.E, nominal=w) w = M.w # Ellipsoidal set # direct lhs = 0 for i, ti in enumerate(tools): for j, tj in enumerate(tools): lhs += (w[ti] - mu[i]) * A[i][j] * (w[tj] - mu[j]) M.E.cons = Constraint(expr=lhs <= 1) # library # An ellipsoidal constraint has the form (w - mu)^T Sig^-1 (w - mu) # EllipsoidalSet takes mu and Sig as arguments (inverse of A above) M.Elib = EllipsoidalSet(mu, Sig) # Polyhedral set # direct M.P = UncSet() M.P.cons = ConstraintList() for i, p in enumerate(P): M.P.cons.add(sum(M.w[t] * p[i] for i, t in enumerate(tools)) <= rhs[i]) # library M.Plib = PolyhedralSet(P, rhs) M.value = Objective(expr=sum(v[i] * M.x[i] for i in M.ITEMS), sense=maximize) M.weight = Constraint(expr=sum(w[i] * M.x[i] for i in M.ITEMS) <= limit) return M
def Knapsack(): v = {'hammer': 8, 'wrench': 3, 'screwdriver': 6, 'towel': 11} w = {'hammer': 5, 'wrench': 7, 'screwdriver': 4, 'towel': 3} limit = 14 M = ConcreteModel() M.ITEMS = Set(initialize=v.keys()) M.x = Var(M.ITEMS, within=Binary) # Define Uncertainty set & uncertain parameters mu = w A = [[0.1, 0.01, 0.0, 0.0], [0.01, 0.1, 0.0, 0.0], [0.0, 0.0, 0.1, 0.0], [0.0, 0.0, 0.0, 0.1]] tools = ['hammer', 'wrench', 'screwdriver', 'towel'] Adict = {(ti, tj): A[i][j] for i, ti in enumerate(tools) for j, tj in enumerate(tools)} perm = itertools.product([1, -1], repeat=len(tools)) P = [dict(zip(tools, i)) for i in perm] rhs = [sum(p[t] * w[t] for t in tools) + 5.5 for p in P] M.E = UncSet() M.w = UncParam(M.ITEMS, uncset=M.E, nominal=w) w = M.w # Ellipsoidal set # direct lhs = 0 for i in M.ITEMS: for j in M.ITEMS: lhs += (w[i] - mu[i]) * Adict[i, j] * (w[j] - mu[j]) M.E.cons = Constraint(expr=lhs <= 1) # library M.Elib = EllipsoidalSet(mu, Adict) # Polyhedral set # direct M.P = UncSet() M.P.cons = ConstraintList() for i, p in enumerate(P): M.P.cons.add(sum(M.w[t] * p[t] for t in tools) <= rhs[i]) # library M.Plib = PolyhedralSet(P, rhs) M.value = Objective(expr=sum(v[i] * M.x[i] for i in M.ITEMS), sense=maximize) M.weight = Constraint(expr=sum(w[i] * M.x[i] for i in M.ITEMS) <= limit) return M
def test_determine_valid_values(self): m = ConcreteModel() m.x = Var() m.y = Var(RangeSet(4), domain=Binary) m.z = Var(domain=Integers, bounds=(-1, 2)) m.constr = Constraint(expr=m.x == m.y[1] + 2 * m.y[2] + m.y[3] + 2 * m.y[4] + m.z) m.logical = ConstraintList() m.logical.add(expr=m.y[1] + m.y[2] == 1) m.logical.add(expr=m.y[3] + m.y[4] == 1) m.logical.add(expr=m.y[2] + m.y[4] <= 1) var_to_values_map = determine_valid_values( m, detect_effectively_discrete_vars(m, 1E-6), Bunch(equality_tolerance=1E-6, pruning_solver='glpk')) valid_values = set([1, 2, 3, 4, 5]) self.assertEqual(set(var_to_values_map[m.x]), valid_values)
def CuttingPlane(C, Subtours): # Number of places n, n = C.shape # Create concrete model model = ConcreteModel() # Set of indices model.I = RangeSet(1, n) model.J = RangeSet(1, n) # Variables model.X = Var(model.I, model.J, within=Binary) # Objective Function model.obj = Objective(expr=sum(C[i - 1, j - 1] * model.X[i, j] for i, j in model.X)) # Constraints on the marginals model.InDegree = Constraint(model.I, rule=lambda m, i: sum(m.X[i, j] for j in m.J) == 1) model.OutDegree = Constraint(model.J, rule=lambda m, j: sum(m.X[i, j] for i in m.I) == 1) model.subtours = ConstraintList() for S in Subtours: P = [(i + 1, j + 1) for i in S for j in S if i != j] model.subtours.add(expr=sum(model.X[i, j] for i, j in P) <= len(S) - 1) #opt.set_instance(model) solver = SolverFactory('gurobi') sol = solver.solve(model, tee=False) # CHECK SOLUTION STATUS # Get a JSON representation of the solution sol_json = sol.json_repn() # Check solution status if sol_json['Solver'][0]['Status'] != 'ok': return None if sol_json['Solver'][0]['Termination condition'] != 'optimal': return None return [(i - 1, j - 1) for i, j in model.X if model.X[i, j]() > 0.5]
def fixedLambdaProblem(L, X, Z, t): model = ConcreteModel() model.nu0 = Var(within=NonNegativeReals) model.nu1 = Var(within=NonNegativeReals) # Vincoli model.denGeqZero = ConstraintList() for row in X: for point in row: model.denGeqZero.add( expr=model.nu0 * minimum_closest(point, L, Z) + model.nu1 >= 0) model.obj = Objective( expr=integrate_LambdaFixed_UB(model.nu0, model.nu1, L, X, Z) + model.nu0 * t + model.nu1) opt = SolverFactory('ipopt') opt.solve(model) return model
def test_induced_linear_in_disjunct(self): m = ConcreteModel() m.x = Var([0], bounds=(-3, 8)) m.y = Var(RangeSet(2), domain=Binary) m.logical = ConstraintList() m.logical.add(expr=m.y[1] + m.y[2] == 1) m.v = Var([1]) m.v[1].setlb(-2) m.v[1].setub(7) m.bilinear_outside = Constraint(expr=m.x[0] * m.v[1] >= 2) m.disjctn = Disjunction( expr=[[m.x[0] * m.v[1] == 3, 2 * m.x[0] == m.y[1] + m.y[2]], [m.x[0] * m.v[1] == 4]]) TransformationFactory('contrib.induced_linearity').apply_to(m) self.assertEqual( m.disjctn.disjuncts[0].constraint[1].body.polynomial_degree(), 1) self.assertEqual(m.bilinear_outside.body.polynomial_degree(), 2) self.assertEqual( m.disjctn.disjuncts[1].constraint[1].body.polynomial_degree(), 2)
def test_stats4(self): model = ConcreteModel() model.x = Var([1]) model.B = Block() model.B.x = Var([1, 2, 3]) model.B.o = ObjectiveList() model.B.o.add(model.B.x[1]) model.B.c = ConstraintList() model.B.c.add(model.B.x[1] == 0) model.B.c.add(model.B.x[2] == 0) model.B.c.add(model.B.x[3] == 0) self.assertEqual(model.nvariables(), 4) self.assertEqual(model.nobjectives(), 1) self.assertEqual(model.nconstraints(), 3) model.clear() self.assertEqual(model.nvariables(), 0) self.assertEqual(model.nobjectives(), 0) self.assertEqual(model.nconstraints(), 0)
def test_rule_option2(self): model = self.create_model() model.B = RangeSet(1,4) def f(model, i): if i > 2: return ConstraintList.End i = 2*i - 1 ans=0 for j in model.B: ans = ans + model.x[j] ans *= i ans = ans <= 0 ans = ans >= 0 return ans model.x = Var(model.B, initialize=2) model.c = ConstraintList(rule=f) self.assertEqual(model.c[1](), 8) self.assertEqual(len(model.c), 2)
def test_rule_option1a(self): model = self.create_model() model.B = RangeSet(1,4) @simple_constraintlist_rule def f(model, i): if i > 4: return None ans=0 for j in model.B: ans = ans + model.x[j] ans *= i ans = ans <= 0 ans = ans >= 0 return ans model.x = Var(model.B, initialize=2) model.c = ConstraintList(rule=f) self.assertEqual(model.c[1](), 8) self.assertEqual(model.c[2](), 16) self.assertEqual(len(model.c), 4)
def create_linear_dual(self, c, b, P, d): ''' Robust constraint: c^T*w <= b for all P*w <= d ''' blk = Block() blk.construct() n, m = len(P), len(P[0]) # Add dual variables blk.var = Var(range(n), within=NonNegativeReals) # Dual objective blk.obj = Constraint(expr=quicksum(d[j]*blk.var[j] for j in range(n)) <= b) # Dual constraints blk.cons = ConstraintList() for i in range(m): lhs = quicksum(P[j][i]*blk.var[j] for j in range(n)) if lhs.__class__ not in native_numeric_types or lhs != 0: blk.cons.add(lhs == c[i]) return blk
class RobustConstraintData(_BlockData): """ RobustConstraint contains: - attribute _cons: constraint - _uncset: uncertainty set - _uncparam: uncertain parameter - _vars: variables the constraint contains """ def __init__(self, component, cons=None): super().__init__(component) self._cons = None self._uncparam = None self._uncset = None self._vars = [] self._sep = None def build(self, lower, expr, upper): # Collect uncertain parameter and uncertainty set self.lower = lower self.upper = upper self._uncparam = _collect_uncparam(expr) self._uncset = [self._uncparam[0]._uncset] self._rule = self.construct_rule(expr) self._bounds = (lower, upper) # Generate nominal constraint nominal_expr = self.nominal_constraint_expr() self._constraints = ConstraintList() self._constraints.add(nominal_expr) def add_cut(self): """ Solve separation problem and add cut. """ sep = self.construct_separation_problem() # TODO: pass option opt = SolverFactory('gurobi') opt.options['NonConvex'] = 2 res = opt.solve(sep) # Check results are okay # Check feasibility? # Generate cut expression: # uncparam = self._uncparam[0] uncparam = sep.uncparam expr = self._rule({i: uncparam[i].value for i in uncparam}) self._constraints.add((self.lower, expr, self.upper)) self.feasible = value(sep.obj <= self.upper) return self.feasible def construct_separation_problem(self): m = ConcreteModel() uncparam = self._uncparam[0] index = uncparam.index_set() # Create inner problem variables # TODO: use setattr to give uncparam same name as in model m.uncparam = Var(index) # collect current coefficient values expr = self._rule(m.uncparam, compute_values=True) # construct objective with current coefficient values m.obj = Objective(expr=expr, sense=maximize) # construct constraints from uncertainty set uncset = self._uncset[0] m.cons = ConstraintList() substitution_map = {id(uncparam[i]): m.uncparam[i] for i in index} for c in uncset.component_data_objects(Constraint): m.cons.add( (c.lower, replace_expressions(c.body, substitution_map), c.upper)) return m # What should we do with the constraints? Replace UncParams by the # Vars? Or restructure UncParam so that we can solve directly.k # !!! def nominal_constraint_expr(self): """ Generate the nominal constraint. """ # TODO: replace p.value by p.nominal uncparam = self._uncparam[0] expr = self._rule({i: uncparam[i].nominal for i in uncparam}) return (self._bounds[0], expr, self._bounds[1]) # !!! def is_feasible(self): return False def construct_rule(self, expr): repn = generate_linear_repn(expr) linear_vars = repn.linear_vars linear_coefs = repn.linear_coefs constant = repn.constant id_coef_dict = {id(v): c for v, c in zip(linear_vars, linear_coefs)} param = self._uncparam[0] index_coef_dict = {i: id_coef_dict.get(id(param[i]), 0) for i in param} def rule(x, compute_values=False): if compute_values: return (quicksum(value(index_coef_dict[i]) * x[i] for i in x) + value(constant)) else: return quicksum(index_coef_dict[i] * x[i] for i in x) + constant return rule
def no_unit(disj, unit): disj.no_flow = ConstraintList() for stream in no_unit_zero_flows[unit]: disj.no_flow.add(expr=m.flow[stream] == 0)
def use_unit(disj, unit): disj.impose_fixed_cost = Constraint(expr=m.yCF[unit] == m.CF[unit]) disj.io_relation = ConstraintList(doc="Input-Output relationship")
elif model.nucleot[i] == 1 and model.nucleot[j] == 3: return model.P[i, j] <= 0 elif model.nucleot[i] == 3 and model.nucleot[j] == 1: return model.P[i, j] <= 0 elif model.nucleot[i] == 2 and model.nucleot[j] == 4: return model.P[i, j] <= 0 elif model.nucleot[i] == 4 and model.nucleot[j] == 2: return model.P[i, j] <= 0 elif model.nucleot[i] == 3 and model.nucleot[j] == 4: return model.P[i, j] <= 0 elif model.nucleot[i] == 4 and model.nucleot[j] == 3: return model.P[i, j] <= 0 return model.P[i, j] <= 1 model.bond_exprs = ConstraintList() for i in range(1, n + 1): for j in range(1, n + 1): model.bond_exprs.add(paired_expr(model, i, j)) def no_cross_rule(model, i, j, h, k): return model.P[i, j] + model.P[h, k] <= 1 model.no_cross_pair = ConstraintList() for i in range(1, n + 1): for j in range(i, n + 1): for h in range(1, i): for k in range(i + 1, j): model.no_cross_pair.add(no_cross_rule(model, i, j, h, k))
def TSPSYM(G): n = G.number_of_nodes() m = ConcreteModel() m.N = RangeSet(n) m.A = Set(initialize=((i, j) for i, j in G.edges()), dimen=2) m.x = Var(m.A, domain=NonNegativeReals, bounds=lambda m: (0, 1)) m.obj = Objective(expr=sum(G[i][j]['weight'] * m.x[i, j] for i, j in G.edges())) m.degree = ConstraintList() for i in m.N: Es = [] for v, w in G.edges(i): if v > w: v, w = w, v Es.append((v, w)) m.degree.add(sum(m.x[v, w] for v, w in Es) == 2) m.subtour = ConstraintList() solver = SolverFactory('gurobi') it = 0 Cold = [] while it <= 100: it += 1 sol = solver.solve(m, tee=False, load_solutions=False) sol_json = sol.json_repn() if sol_json['Solver'][0]['Status'] != 'ok': return None, [] m.solutions.load_from(sol) print(it, 'LP:', m.obj()) selected = [] values = [] for i, j in m.A: if i < j: if m.x[i, j]() > 0.0001: selected.append((i - 1, j - 1)) values.append(m.x[i, j]()) PlotTour(Ls, selected, values) # Costruiamo un grafo supporto H = nx.Graph() for i, j in m.A: H.add_edge(i, j, weight=m.x[i, j]()) cut_value, S = nx.stoer_wagner(H) # Taglio di peso minimo if cut_value >= 2: break Es = [] for i in S[0]: for j in S[1]: if i < j: Es.append((i, j)) else: Es.append((j, i)) m.subtour.add(sum(m.x[i, j] for i, j in Es) >= 2) return m.obj(), selected