def test_tan(self): m = pe.Block(concrete=True) m.x = pe.Var(bounds=(-math.pi/2, math.pi/2)) m.c = pe.Constraint(expr=pe.inequality(body=pe.tan(m.x), lower=-0.5, upper=0.5)) fbbt(m) self.assertAlmostEqual(pe.value(m.x.lb), math.atan(-0.5)) self.assertAlmostEqual(pe.value(m.x.ub), math.atan(0.5)) m = pe.Block(concrete=True) m.x = pe.Var() m.c = pe.Constraint(expr=pe.inequality(body=pe.tan(m.x), lower=-0.5, upper=0.5)) fbbt(m) self.assertEqual(m.x.lb, None) self.assertEqual(m.x.ub, None)
def test_add(self): x_bounds = [(-2.5, 2.8), (-2.5, -0.5), (0.5, 2.8), (-2.5, 0), (0, 2.8), (-2.5, -1), (1, 2.8), (-1, -0.5), (0.5, 1)] c_bounds = [(-2.5, 2.8), (-2.5, -0.5), (0.5, 2.8), (-2.5, 0), (0, 2.8), (-2.5, -1), (1, 2.8), (-1, -0.5), (0.5, 1)] for xl, xu in x_bounds: for cl, cu in c_bounds: m = pe.Block(concrete=True) m.x = pe.Var(bounds=(xl, xu)) m.y = pe.Var() m.p = pe.Param(mutable=True) m.p.value = 1 m.c = pe.Constraint(expr=pe.inequality(body=m.x+m.y+(m.p+1), lower=cl, upper=cu)) new_bounds = fbbt(m) self.assertEqual(new_bounds[m.x], (pe.value(m.x.lb), pe.value(m.x.ub))) self.assertEqual(new_bounds[m.y], (pe.value(m.y.lb), pe.value(m.y.ub))) x = np.linspace(pe.value(m.x.lb), pe.value(m.x.ub), 100) z = np.linspace(pe.value(m.c.lower), pe.value(m.c.upper), 100) if m.y.lb is None: yl = -np.inf else: yl = m.y.lb if m.y.ub is None: yu = np.inf else: yu = m.y.ub for _x in x: _y = z - _x - m.p.value - 1 self.assertTrue(np.all(yl <= _y)) self.assertTrue(np.all(yu >= _y))
def test_asin(self): m = pe.Block(concrete=True) m.x = pe.Var() m.c = pe.Constraint(expr=pe.inequality(body=pe.asin(m.x), lower=-0.5, upper=0.5)) fbbt(m) self.assertAlmostEqual(pe.value(m.x.lb), math.sin(-0.5)) self.assertAlmostEqual(pe.value(m.x.ub), math.sin(0.5))
def test_acos(self): m = pe.Block(concrete=True) m.x = pe.Var() m.c = pe.Constraint(expr=pe.inequality(body=pe.acos(m.x), lower=1, upper=2)) fbbt(m) self.assertAlmostEqual(pe.value(m.x.lb), math.cos(2)) self.assertAlmostEqual(pe.value(m.x.ub), math.cos(1))
def test_stoch_range_constraint(self): model = self._get_base_model() model.q = aml.Param(mutable=True, initialize=0.0) model.stochdata.declare( model.q, distribution=TableDistribution([0.0,1.0])) model.c3 = aml.Constraint(expr=aml.inequality(model.q, model.y, 0)) sp = EmbeddedSP(model) with self.assertRaises(ValueError) as cm: pyomo.pysp.convert.smps.convert_embedded(self.tmpdir, 'test', sp) self.assertEqual( str(cm.exception), ("Cannot output embedded SP representation for component " "'c3'. The embedded SMPS writer does not yet handle range " "constraints that have stochastic data."))
def test_mutable_novalue_param_equality(self): model = ConcreteModel() model.x = Var() model.p = Param(mutable=True) model.p.value = None model.c = Constraint(expr=model.x - model.p == 0) self.assertEqual(model.c.equality, True) model.del_component(model.c) model.c = Constraint(expr=model.x == model.p) self.assertTrue(model.c.upper is model.p) self.assertEqual(model.c.equality, True) model.del_component(model.c) model.c = Constraint(expr=model.x + 1 == model.p) self.assertEqual(model.c.equality, True) model.del_component(model.c) model.c = Constraint(expr=model.x + 1 == (model.p + 1)**2) self.assertEqual(model.c.equality, True) model.del_component(model.c) model.c = Constraint(expr=model.x == model.p + 1) self.assertEqual(model.c.equality, True) model.del_component(model.c) model.c = Constraint(expr=inequality(model.p, model.x, model.p)) self.assertTrue(model.c.upper is model.p) # GH: Not sure if we are supposed to detect equality # in this situation. I would rather us not, for # the sake of making the code less complicated. # Either way, I am not going to test for it here. #self.assertEqual(model.c.equality, <blah>) model.del_component(model.c) model.c = Constraint(expr=(model.x, model.p)) self.assertTrue(model.c.upper is model.p) self.assertEqual(model.c.equality, True) model.del_component(model.c) model.c = Constraint(expr=(model.p, model.x)) self.assertTrue(model.c.upper is model.p) self.assertEqual(model.c.equality, True) model.del_component(model.c)
def test_log(self): c_bounds = [(-2.5, 2.8), (-2.5, -0.5), (0.5, 2.8), (-2.5, 0), (0, 2.8), (-2.5, -1), (1, 2.8), (-1, -0.5), (0.5, 1)] for cl, cu in c_bounds: m = pe.Block(concrete=True) m.x = pe.Var() m.c = pe.Constraint(expr=pe.inequality(body=pe.log(m.x), lower=cl, upper=cu)) fbbt(m) z = np.linspace(pe.value(m.c.lower), pe.value(m.c.upper), 100) if m.x.lb is None: xl = -np.inf else: xl = pe.value(m.x.lb) if m.x.ub is None: xu = np.inf else: xu = pe.value(m.x.ub) x = np.exp(z) self.assertTrue(np.all(xl <= x)) self.assertTrue(np.all(xu >= x))
def EDLP_Trade_Spent_Bnd_Stg_inter_Fn(Model, Cur_Ret): """Define pyomo callback for calculating bound for EDLP trade spent. Parameters ---------- Model : Pyomo Model Object created with the required variables Cur_Ret : Integer, PPG number to calculate EDLP Trade Spent for all the weeks . Will be iteratively called by Model Objective function Returns: -------- Pyomo Expression, containing product EDLP Trade Spent equation """ Val = sum([(Globals.Base_Price_stg2[Cur_Ret][Wk] - Retailer_Price_inter_Fn(Model, Cur_Ret, Wk)) * Retailer_Unit_Sales_Stg_inter_Fn(Model, Cur_Ret, Wk) * (Model.FLAG[Cur_Ret, Wk]) for Wk in Model.Wk_index]) return pyo.inequality( Globals.Target_EDLP_Spend[Cur_Ret] * (1 - Globals.EDLP_Perc_Limit / 100), Val, Globals.Target_EDLP_Spend[Cur_Ret] * (1 + Globals.EDLP_Perc_Limit / 100), )
def test_exp(self): c_bounds = [(-2.5, 2.8), (0.5, 2.8), (0, 2.8), (1, 2.8), (0.5, 1)] for cl, cu in c_bounds: m = pe.Block(concrete=True) m.x = pe.Var() m.c = pe.Constraint(expr=pe.inequality(body=pe.exp(m.x), lower=cl, upper=cu)) fbbt(m) if pe.value(m.c.lower) <= 0: _cl = 1e-6 else: _cl = pe.value(m.c.lower) z = np.linspace(_cl, pe.value(m.c.upper), 100) if m.x.lb is None: xl = -np.inf else: xl = pe.value(m.x.lb) if m.x.ub is None: xu = np.inf else: xu = pe.value(m.x.ub) x = np.log(z) self.assertTrue(np.all(xl <= x)) self.assertTrue(np.all(xu >= x))
def test_log(self): if not numpy_available: raise unittest.SkipTest('Numpy is not available') c_bounds = [(-2.5, 2.8), (-2.5, -0.5), (0.5, 2.8), (-2.5, 0), (0, 2.8), (-2.5, -1), (1, 2.8), (-1, -0.5), (0.5, 1)] for cl, cu in c_bounds: m = pyo.Block(concrete=True) m.x = pyo.Var() m.c = pyo.Constraint( expr=pyo.inequality(body=pyo.log(m.x), lower=cl, upper=cu)) self.tightener(m) z = np.linspace(pyo.value(m.c.lower), pyo.value(m.c.upper), 100) if m.x.lb is None: xl = -np.inf else: xl = pyo.value(m.x.lb) if m.x.ub is None: xu = np.inf else: xu = pyo.value(m.x.ub) x = np.exp(z) self.assertTrue(np.all(xl <= x)) self.assertTrue(np.all(xu >= x))
def test_log10(self): c_bounds = [(-2.5, 2.8), (-2.5, -0.5), (0.5, 2.8), (-2.5, 0), (0, 2.8), (-2.5, -1), (1, 2.8), (-1, -0.5), (0.5, 1)] for cl, cu in c_bounds: m = pe.Block(concrete=True) m.x = pe.Var() m.c = pe.Constraint( expr=pe.inequality(body=pe.log10(m.x), lower=cl, upper=cu)) fbbt(m) z = np.linspace(pe.value(m.c.lower), pe.value(m.c.upper), 100) if m.x.lb is None: xl = -np.inf else: xl = pe.value(m.x.lb) if m.x.ub is None: xu = np.inf else: xu = pe.value(m.x.ub) x = 10**z print(xl, xu, cl, cu) print(x) self.assertTrue(np.all(xl <= x)) self.assertTrue(np.all(xu >= x))
def test_sub2(self): x_bounds = [(-2.5, 2.8), (-2.5, -0.5), (0.5, 2.8), (-2.5, 0), (0, 2.8), (-2.5, -1), (1, 2.8), (-1, -0.5), (0.5, 1)] c_bounds = [(-2.5, 2.8), (-2.5, -0.5), (0.5, 2.8), (-2.5, 0), (0, 2.8), (-2.5, -1), (1, 2.8), (-1, -0.5), (0.5, 1)] for xl, xu in x_bounds: for cl, cu in c_bounds: m = pe.Block(concrete=True) m.x = pe.Var(bounds=(xl, xu)) m.y = pe.Var() m.c = pe.Constraint(expr=pe.inequality(body=m.y-m.x, lower=cl, upper=cu)) fbbt(m) x = np.linspace(pe.value(m.x.lb), pe.value(m.x.ub), 100) z = np.linspace(pe.value(m.c.lower), pe.value(m.c.upper), 100) if m.y.lb is None: yl = -np.inf else: yl = m.y.lb if m.y.ub is None: yu = np.inf else: yu = m.y.ub for _x in x: _y = z + _x self.assertTrue(np.all(yl <= _y)) self.assertTrue(np.all(yu >= _y))
def test_pow1(self): x_bounds = [(0, 2.8), (0.5, 2.8), (1, 2.8), (0.5, 1)] c_bounds = [(-2.5, 2.8), (0.5, 2.8), (-2.5, 0), (0, 2.8), (1, 2.8), (0.5, 1)] for xl, xu in x_bounds: for cl, cu in c_bounds: m = pyo.Block(concrete=True) m.x = pyo.Var(bounds=(xl, xu)) m.y = pyo.Var() m.c = pyo.Constraint( expr=pyo.inequality(body=m.x**m.y, lower=cl, upper=cu)) if xl > 0 and cu <= 0: with self.assertRaises(InfeasibleConstraintException): fbbt(m) else: fbbt(m) x = np.linspace(pyo.value(m.x.lb) + 1e-6, pyo.value(m.x.ub), 100, endpoint=False) z = np.linspace(pyo.value(m.c.lower) + 1e-6, pyo.value(m.c.upper), 100, endpoint=False) if m.y.lb is None: yl = -np.inf else: yl = m.y.lb if m.y.ub is None: yu = np.inf else: yu = m.y.ub for _x in x: _y = np.log(abs(z)) / np.log(abs(_x)) self.assertTrue(np.all(yl <= _y)) self.assertTrue(np.all(yu >= _y))
def test_pow2(self): x_bounds = [(-2.5, 2.8), (-2.5, -0.5), (0.5, 2.8), (-2.5, 0), (0, 2.8), (-2.5, -1), (1, 2.8), (-1, -0.5), (0.5, 1)] c_bounds = [(-2.5, 2.8), (-2.5, -0.5), (0.5, 2.8), (-2.5, 0), (0, 2.8), (-2.5, -1), (1, 2.8), (-1, -0.5), (0.5, 1)] for xl, xu in x_bounds: for cl, cu in c_bounds: m = pe.Block(concrete=True) m.x = pe.Var(bounds=(xl, xu)) m.y = pe.Var() m.c = pe.Constraint( expr=pe.inequality(body=m.y**m.x, lower=cl, upper=cu)) fbbt(m) x = np.linspace(pe.value(m.x.lb) + 1e-6, pe.value(m.x.ub), 100, endpoint=False) z = np.linspace(pe.value(m.c.lower) + 1e-6, pe.value(m.c.upper), 100, endpoint=False) if m.y.lb is None: yl = -np.inf else: yl = m.y.lb if m.y.ub is None: yu = np.inf else: yu = m.y.ub for _x in x: _y = np.exp(np.log(abs(z)) / _x) self.assertTrue(np.all(yl <= _y)) self.assertTrue(np.all(yu >= _y)) _y = -_y self.assertTrue(np.all(yl <= _y)) self.assertTrue(np.all(yu >= _y))
def test_pow1(self): x_bounds = [(0, 2.8), (0.5, 2.8), (1, 2.8), (0.5, 1)] c_bounds = [(-2.5, 2.8), (0.5, 2.8), (-2.5, 0), (0, 2.8), (1, 2.8), (0.5, 1)] for xl, xu in x_bounds: for cl, cu in c_bounds: m = pe.Block(concrete=True) m.x = pe.Var(bounds=(xl, xu)) m.y = pe.Var() m.c = pe.Constraint(expr=pe.inequality(body=m.x**m.y, lower=cl, upper=cu)) fbbt(m) x = np.linspace(pe.value(m.x.lb) + 1e-6, pe.value(m.x.ub), 100, endpoint=False) z = np.linspace(pe.value(m.c.lower) + 1e-6, pe.value(m.c.upper), 100, endpoint=False) if m.y.lb is None: yl = -np.inf else: yl = m.y.lb if m.y.ub is None: yu = np.inf else: yu = m.y.ub for _x in x: _y = np.log(abs(z)) / np.log(abs(_x)) self.assertTrue(np.all(yl <= _y)) self.assertTrue(np.all(yu >= _y))
def test_sub1(self): x_bounds = [(-2.5, 2.8), (-2.5, -0.5), (0.5, 2.8), (-2.5, 0), (0, 2.8), (-2.5, -1), (1, 2.8), (-1, -0.5), (0.5, 1)] c_bounds = [(-2.5, 2.8), (-2.5, -0.5), (0.5, 2.8), (-2.5, 0), (0, 2.8), (-2.5, -1), (1, 2.8), (-1, -0.5), (0.5, 1)] for xl, xu in x_bounds: for cl, cu in c_bounds: m = pe.Block(concrete=True) m.x = pe.Var(bounds=(xl, xu)) m.y = pe.Var() m.c = pe.Constraint(expr=pe.inequality(body=m.x-m.y, lower=cl, upper=cu)) fbbt(m) x = np.linspace(pe.value(m.x.lb), pe.value(m.x.ub), 100) z = np.linspace(pe.value(m.c.lower), pe.value(m.c.upper), 100) if m.y.lb is None: yl = -np.inf else: yl = m.y.lb if m.y.ub is None: yu = np.inf else: yu = m.y.ub for _x in x: _y = _x - z self.assertTrue(np.all(yl <= _y)) self.assertTrue(np.all(yu >= _y))
def _apply_to(self, instance): for c in chain( self.get_adjustable_components(instance), self.get_adjustable_components(instance, component=Objective)): # Collect adjustable var adjvar = collect_adjustable(c) # Get regular var if adjvar.name not in self._adjvar_dict: var = Var(adjvar.index_set(), bounds=adjvar._bounds_init_value) setattr(instance, adjvar.name + '_nominal', var) self._adjvar_dict[adjvar.name] = var for i in adjvar: var[i].fixed = adjvar[i].fixed var[i].setlb(adjvar[i].lb) var[i].setub(adjvar[i].ub) var[i].value = adjvar[i].value else: var = self._adjvar_dict[adjvar.name] # Construct substitution map sub_map = {id(adjvar[i]): var[i] for i in adjvar} # Replace AdjustableVar with Var if c.ctype is Objective: e_new = replace_expressions(c.expr, substitution_map=sub_map) c_new = Objective(expr=e_new, sense=c.sense) else: e_new = replace_expressions(c.body, substitution_map=sub_map) if c.equality: c_new = Constraint(expr=e_new == c.upper) else: c_new = Constraint( expr=inequality(c.lower, e_new, c.upper)) setattr(instance, c.name + '_nominal', c_new) self._cons_dict[c.name] = (c, c_new) c.deactivate()
def G4_rule(model): valueG4 = sum(model.x[i] * 100 for i in model.G4) return environ.inequality(model.minG4, valueG4, model.maxG4)
#obj function model.obj = pyo.Objective(expr=pyo.summation(x), sense=pyo.maximize) #constraints model.C1 = pyo.ConstraintList() for t in range(1, T + 1): model.C1.add(expr=2 * x[2, t] - 8 * x[3, t] <= 0) model.C2 = pyo.ConstraintList() for t in range(3, T + 1): model.C2.add(expr=x[2, t] - 2 * x[3, t - 2] + x[4, t] >= 1) model.C3 = pyo.ConstraintList() for t in range(1, T + 1): model.C3.add(expr=sum([x[m, t] for m in range(1, M + 1)]) <= 50) model.C4 = pyo.ConstraintList() for t in range(2, T + 1): model.C4.add(expr=x[1, t] + x[2, t - 1] + x[3, t] + x[4, t] <= 10) model.C5 = pyo.ConstraintList() for m in range(1, M + 1): for t in range(1, T + 1): model.C5.add(pyo.inequality(0, x[m, t], 10)) #solve opt = SolverFactory('glpk', executable='/usr/local/bin/glpsol') opt.options["mipgap"] = 0 results = opt.solve(model, tee=True, timelimit=10) print(pyo.value(model.obj))
def model(self): model = pyo.ConcreteModel(name=self._name) # build variables default_var_lb = self._l_default default_var_ub = self._u_default default_var_x0 = self._x0_default variables = [] for i in range(self._num_variables): idx = i + 1 var_type = VAR_TYPES[self._v_entries.get(idx, self._v_default)] var_name = self._var_name_nnz_entries.get(idx, 'x{}'.format(idx)) var_lb = self._l_entries.get(idx, default_var_lb) var_ub = self._u_entries.get(idx, default_var_ub) var_x0 = self._x0_entries.get(idx, default_var_x0) if var_type in [pyo.Integers, pyo.Binary]: var_x0 = int(var_x0) var = pyo.Var(name=var_name, domain=var_type, bounds=(var_lb, var_ub), initialize=lambda _: var_x0) variables.append(var) setattr(model, var_name, var) # build objective obj_quad = self._obj_const for (i, j), q in self._obj_q_entries.items(): # d = 2.0 if i == j else 1.0 d = 2.0 obj_quad += (q / d) * variables[i - 1] * variables[j - 1] obj_linear = pyo.quicksum([ v * self._obj_b_entries.get(i + 1, self._b0_default) for i, v in enumerate(variables) ], linear=False) model.obj = pyo.Objective(expr=obj_quad + obj_linear, sense=self._sense) # build constraints for i in range(self._num_constraints): con_idx = i + 1 con_quad = 0.0 if con_idx not in self._con_q_entries and con_idx not in self._con_b_entries: continue if con_idx in self._con_q_entries: for (h, k), q in self._con_q_entries[con_idx].items(): # d = 2.0 if h == k else 1.0 d = 2.0 con_quad += (q / d) * variables[h - 1] * variables[k - 1] con_linear = 0.0 if con_idx in self._con_b_entries: con_linear = pyo.quicksum( [ b * variables[j - 1] for j, b in self._con_b_entries[con_idx].items() ], linear=False, ) con_name = self._con_name_nnz_entries.get(i + 1, 'e{}'.format(i + 1)) con_lb = self._cl_entries.get(i + 1, self._cl_default) con_ub = self._cu_entries.get(i + 1, self._cu_default) con_expr = pyo.inequality(con_lb, con_quad + con_linear, con_ub) con = pyo.Constraint(name=con_name, expr=con_expr) setattr(model, con_name, con) return model
def test_compoundInequality(self): m = self.m # < # / \ # < c # / \ # a b e = inequality(m.a, m.b, m.c, strict=True) self.assertIs(type(e), RangedExpression) self.assertEqual(e.nargs(), 3) self.assertIs(e.arg(0), m.a) self.assertIs(e.arg(1), m.b) self.assertIs(e.arg(2), m.c) #self.assertEqual(len(e._strict), 2) self.assertEqual(e._strict[0], True) self.assertEqual(e._strict[1], True) # <= # / \ # <= c # / \ # a b e = inequality(m.a, m.b, m.c) self.assertIs(type(e), RangedExpression) self.assertEqual(e.nargs(), 3) self.assertIs(e.arg(0), m.a) self.assertIs(e.arg(1), m.b) self.assertIs(e.arg(2), m.c) #self.assertEqual(len(e._strict), 2) self.assertEqual(e._strict[0], False) self.assertEqual(e._strict[1], False) # > # / \ # > c # / \ # a b e = inequality(upper=m.c, body=m.b, lower=m.a, strict=True) self.assertIs(type(e), RangedExpression) self.assertEqual(e.nargs(), 3) self.assertIs(e.arg(2), m.c) self.assertIs(e.arg(1), m.b) self.assertIs(e.arg(0), m.a) #self.assertEqual(len(e._strict), 2) self.assertEqual(e._strict[0], True) self.assertEqual(e._strict[1], True) # >= # / \ # >= c # / \ # a b e = inequality(upper=m.c, body=m.b, lower=m.a) self.assertIs(type(e), RangedExpression) self.assertEqual(e.nargs(), 3) self.assertIs(e.arg(2), m.c) self.assertIs(e.arg(1), m.b) self.assertIs(e.arg(0), m.a) #self.assertEqual(len(e._strict), 2) self.assertEqual(e._strict[0], False) self.assertEqual(e._strict[1], False) # <= # / \ # <= 0 # / \ # 0 a e = inequality(0, m.a, 0) self.assertIs(type(e), RangedExpression) self.assertEqual(e.nargs(), 3) self.assertIs(e.arg(2), 0) self.assertIs(e.arg(1), m.a) self.assertIs(e.arg(0), 0) #self.assertEqual(len(e._strict), 2) self.assertEqual(e._strict[0], False) self.assertEqual(e._strict[1], False) # < # / \ # < 0 # / \ # 0 a e = inequality(0, m.a, 0, True) self.assertIs(type(e), RangedExpression) self.assertEqual(e.nargs(), 3) self.assertIs(e.arg(2), 0) self.assertIs(e.arg(1), m.a) self.assertIs(e.arg(0), 0) #self.assertEqual(len(e._strict), 2) self.assertEqual(e._strict[0], True) self.assertEqual(e._strict[1], True)
def G2_rule(model): valueG2 = sum(model.x[i] * 100 for i in model.G2) return environ.inequality(model.minG2, valueG2, model.maxG2)
def sugar_rule(model): return environ.inequality(0.00, model.x['Sugar'], 0.05)
# @Constraints_dict def cd_(m,i,j): return m.vd[i] == j m.cd = aml.Constraint(m.s, m.q, rule=cd_) # @Constraints_dict # @Constraints_list # uses 1-based indexing m.cl = aml.ConstraintList() for j in m.q: m.cl.add( aml.inequality( -5, m.vl[j]-m.v, 5)) # @Constraints_list # @Expressions_single m.e = aml.Expression(expr=-m.v) # @Expressions_single # @Expressions_dict def ed_(m, i): return -m.vd[i] m.ed = aml.Expression(m.s, rule=ed_) # @Expressions_dict # @Expressions_list
def test_relational_ops(self): # # Relation of mutable parameters: fixed, not constant, pvar # expr = self.instance.c < self.instance.d self.assertEqual(expr.is_fixed(), True) self.assertEqual(expr.is_constant(), False) self.assertEqual(expr.is_potentially_variable(), False) expr = inequality(0, self.instance.c, self.instance.d) self.assertEqual(expr.is_fixed(), True) self.assertEqual(expr.is_constant(), False) self.assertEqual(expr.is_potentially_variable(), False) expr = self.instance.c == self.instance.d self.assertEqual(expr.is_fixed(), True) self.assertEqual(expr.is_constant(), False) self.assertEqual(expr.is_potentially_variable(), False) # # Relation of unfixed variable and mutable parameters: not fixed, not constant, pvar # expr = self.instance.a <= self.instance.d self.assertEqual(expr.is_fixed(), False) self.assertEqual(expr.is_constant(), False) self.assertEqual(expr.is_potentially_variable(), True) expr = inequality(0, self.instance.a, self.instance.d) self.assertEqual(expr.is_fixed(), False) self.assertEqual(expr.is_constant(), False) self.assertEqual(expr.is_potentially_variable(), True) expr = self.instance.a == self.instance.d self.assertEqual(expr.is_fixed(), False) self.assertEqual(expr.is_constant(), False) self.assertEqual(expr.is_potentially_variable(), True) # # Relation of unfixed variables: not fixed, not constant, pvar # expr = self.instance.a * self.instance.a >= self.instance.b self.assertEqual(expr.is_fixed(), False) self.assertEqual(expr.is_constant(), False) self.assertEqual(expr.is_potentially_variable(), True) expr = self.instance.a * self.instance.a == self.instance.b self.assertEqual(expr.is_fixed(), False) self.assertEqual(expr.is_constant(), False) self.assertEqual(expr.is_potentially_variable(), True) expr = inequality(self.instance.b, self.instance.a * self.instance.a, 0) self.assertEqual(expr.is_fixed(), False) self.assertEqual(expr.is_constant(), False) self.assertEqual(expr.is_potentially_variable(), True) # # Relation of fixed and unfixed variables: not fixed, not constant, pvar # self.instance.a.fixed = True self.assertEqual(expr.is_fixed(), False) self.assertEqual(expr.is_constant(), False) self.assertEqual(expr.is_potentially_variable(), True) # # Relation of fixed variables: fixed, not constant, pvar # self.instance.b.fixed = True self.assertEqual(expr.is_fixed(), True) self.assertEqual(expr.is_constant(), False) self.assertEqual(expr.is_potentially_variable(), True)
def relax(model, descend_into=None, in_place=False, use_fbbt=True): if not in_place: m = model.clone() else: m = model if descend_into is None: descend_into = (pe.Block, Disjunct) aux_var_map = dict() counter_dict = dict() degree_map = ComponentMap() for c in m.component_data_objects(ctype=Constraint, active=True, descend_into=descend_into, sort=True): body_degree = polynomial_degree(c.body) if body_degree is not None: if body_degree <= 1: continue if c.lower is not None and c.upper is not None: relaxation_side = RelaxationSide.BOTH elif c.lower is not None: relaxation_side = RelaxationSide.OVER elif c.upper is not None: relaxation_side = RelaxationSide.UNDER else: raise ValueError('Encountered a constraint without a lower or an upper bound: ' + str(c)) parent_block = c.parent_block() relaxation_side_map = ComponentMap() relaxation_side_map[c.body] = relaxation_side if parent_block in counter_dict: counter = counter_dict[parent_block] else: parent_block.relaxations = pe.Block() parent_block.aux_vars = pe.VarList() parent_block.aux_cons = pe.ConstraintList() counter = RelaxationCounter() counter_dict[parent_block] = counter new_body = _relax_expr(expr=c.body, aux_var_map=aux_var_map, parent_block=parent_block, relaxation_side_map=relaxation_side_map, counter=counter, degree_map=degree_map) lb = c.lower ub = c.upper parent_block.aux_cons.add(pe.inequality(lb, new_body, ub)) parent_component = c.parent_component() if parent_component.is_indexed(): del parent_component[c.index()] else: parent_block.del_component(c) for c in m.component_data_objects(ctype=pe.Objective, active=True, descend_into=descend_into, sort=True): degree = polynomial_degree(c.expr) if degree is not None: if degree <= 1: continue if c.sense == pe.minimize: relaxation_side = RelaxationSide.UNDER elif c.sense == pe.maximize: relaxation_side = RelaxationSide.OVER else: raise ValueError('Encountered an objective with an unrecognized sense: ' + str(c)) parent_block = c.parent_block() relaxation_side_map = ComponentMap() relaxation_side_map[c.expr] = relaxation_side if parent_block in counter_dict: counter = counter_dict[parent_block] else: parent_block.relaxations = pe.Block() parent_block.aux_vars = pe.VarList() parent_block.aux_cons = pe.ConstraintList() counter = RelaxationCounter() counter_dict[parent_block] = counter if not hasattr(parent_block, 'aux_objectives'): parent_block.aux_objectives = pe.ObjectiveList() new_body = _relax_expr(expr=c.expr, aux_var_map=aux_var_map, parent_block=parent_block, relaxation_side_map=relaxation_side_map, counter=counter, degree_map=degree_map) sense = c.sense parent_block.aux_objectives.add(new_body, sense=sense) parent_component = c.parent_component() if parent_component.is_indexed(): del parent_component[c.index()] else: parent_block.del_component(c) if use_fbbt: for _aux_var, relaxation in aux_var_map.values(): relaxation.rebuild(build_nonlinear_constraint=True) fbbt(m, deactivate_satisfied_constraints=True) for _aux_var, relaxation in aux_var_map.values(): relaxation.use_linear_relaxation = True relaxation.rebuild() else: for _aux_var, relaxation in aux_var_map.values(): relaxation.use_linear_relaxation = True relaxation.rebuild() return m
def G5_rule(model): valueG5 = sum(model.x[i] * 100 for i in model.G5) return environ.inequality(model.minG5, valueG5, model.maxG5)
else: return model.StartTime[t] <= model.StartTime[t + 1] model.Pred = pyo.Constraint(TimePeriods, rule=Pred_rule) # @:decl6 model.pprint() model = None # @slack: model = pyo.ConcreteModel() model.x = pyo.Var(initialize=1.0) model.y = pyo.Var(initialize=1.0) model.c1 = pyo.Constraint(expr=model.y - model.x <= 7.5) model.c2 = pyo.Constraint(expr=-2.5 <= model.y - model.x) model.c3 = pyo.Constraint(expr=pyo.inequality(-3.0, model.y - model.x, 7.0)) print(pyo.value(model.c1.body)) # 0.0 print(model.c1.lslack()) # inf print(model.c1.uslack()) # 7.5 print(model.c2.lslack()) # 2.5 print(model.c2.uslack()) # inf print(model.c3.lslack()) # 3.0 print(model.c3.uslack()) # 7.0 # @:slack model.display()
def salt_rule(model): return environ.inequality(0.05, model.x['Salt'], 1)
def eq7_rule(model, s, t, b): return pyo.inequality(model.V_, model.V_stb[s, t, b], model.Vup)
def G1_rule(model): valueG1 = sum(model.x[i] * 100 for i in model.G1) return environ.inequality(model.minG1, valueG1, model.maxG1)
def create_model(): """Create a :class:`pyomo.environ.AbstracModel` for the diet problem""" m = AbstractModel("diet") #-------------------------- # Sets #-------------------------- m.F = Set(doc="Foods. :math:`\\mathcal{F}`") m.N = Set(doc="Nutrients. :math:`\\mathcal{N}`") #-------------------------- # Parameters #-------------------------- m.cost = Param(m.F, within=pe.NonNegativeReals, doc="""Cost of each food. :math:`c_f \\geq 0`""") m.content = Param(m.F, m.N, within=pe.NonNegativeReals, doc="""Amount of nutrient in each food. :math:`a_{f,n} \\geq 0`""") m.min_intake = Param(m.N, within=pe.NonNegativeReals, default=0.0, doc="""Lower bound on each nutrient. :math:`y^{min}_n`""") m.max_intake = Param(m.N, within=pe.NonNegativeReals, default=infinity, doc="""Upper bound on each nutrient. :math:`y^{max}_n`""") m.volume = Param(m.F, within=pe.PositiveReals, doc="""Volume per serving of food. :math:`v_f`""") m.max_volume = Param(within=pe.PositiveReals, doc="""Maximum volume of food consumed. :math:`v^{max}`""") #-------------------------- # Variables #-------------------------- m.x = Var(m.F, within=pe.NonNegativeIntegers, doc="""Number of servings consumed of each food. :math:`x_f \\geq 0`""") #-------------------------- # Expressions #-------------------------- m.total_volume = Expression(rule=lambda m: pe.summation(m.volume, m.x), doc="""Total volume of food consumed. \n .. math:: v^{tot} = \\sum_{f \\in \\mathcal{F}} v_f \\cdot x_f""") m.intake = Expression(m.N, rule=lambda m, n: sum(m.content[f, n] * m.x[f] for f in m.F), doc="""Total intake of each nutrient. \n .. math:: y_n = \\sum_{f \\in \\mathcal{F}} \\alpha_{f,n} \\cdot x_f""") #-------------------------- # Objective #-------------------------- m.minimize_total_cost = Objective( rule=lambda m: pe.summation(m.cost, m.x), doc="""Minimize the cost of food that is consumed. \n .. math:: \\min_{x} \\sum_{f \\in \\mathcal{F}} c_f \\cdot x_f""") #-------------------------- # Constraints #-------------------------- m.nutrient_limit = Constraint( m.N, rule=lambda m, n: inequality(m.min_intake[n], m.intake[n], m. max_intake[n]), doc="""Enforce upper and lower bounds on intake of each nutrient. \n .. math:: y^{min}_n \\leq y_n \\leq y^{max}_n""") m.volume_limit = Constraint(expr=m.total_volume <= m.max_volume, doc="""Limit the volume of food consumed. \n .. math:: v^{tot} \\leq v^{max}""") return m
def test_simpleInequality2(self): # # Check the structure of a simple inequality # m = self.m # < # / \ # a b e = inequality(lower=m.a, body=m.b, strict=True) self.assertIs(type(e), InequalityExpression) self.assertEqual(e.nargs(), 2) self.assertIs(e.arg(0), m.a) self.assertIs(e.arg(1), m.b) #self.assertEqual(len(e._strict), 1) self.assertEqual(e._strict, True) # <= # / \ # a b e = inequality(lower=m.a, upper=m.b) self.assertIs(type(e), InequalityExpression) self.assertEqual(e.nargs(), 2) self.assertIs(e.arg(0), m.a) self.assertIs(e.arg(1), m.b) #self.assertEqual(len(e._strict), 1) self.assertEqual(e._strict, False) # > # / \ # a b e = inequality(lower=m.b, upper=m.a, strict=True) self.assertIs(type(e), InequalityExpression) self.assertEqual(e.nargs(), 2) self.assertIs(e.arg(0), m.b) self.assertIs(e.arg(1), m.a) #self.assertEqual(len(e._strict), 1) self.assertEqual(e._strict, True) # >= # / \ # a b e = m.a >= m.b e = inequality(body=m.b, upper=m.a) self.assertIs(type(e), InequalityExpression) self.assertEqual(e.nargs(), 2) self.assertIs(e.arg(0), m.b) self.assertIs(e.arg(1), m.a) #self.assertEqual(len(e._strict), 1) self.assertEqual(e._strict, False) try: inequality(None, None) self.fail("expected invalid inequality error.") except ValueError: pass try: inequality(m.a, None) self.fail("expected invalid inequality error.") except ValueError: pass
def d_nonzero_rule(d, k): m = d.model() d.c = pyo.Constraint(expr=pyo.inequality(L[k], m.x[k], U[k])) d.count = pyo.Constraint(expr=m.x_nonzero[k] == 1)
def _con(m, i): return inequality(m.vmin[i]**2, m.v[i], m.vmax[i]**2)
def _add_grouping_constraint(self, sensor_list, select=None, min_select=None, max_select=None): #TODO: Should we make this easier by just allowing lower bound and #upper bound and do an equality if they are the same? if self._model is None: raise RuntimeError('Cannot add a grouping constraint to a' 'nonexistent model. Please call the ' 'create_pyomo_model function before trying to ' 'add grouping constraints') if select is not None and min_select is not None: raise ValueError('Invalid keyword arguments for adding grouping ' 'constraint. Cannot specify both a "select" ' 'value and a "min_select" value') if select is not None and max_select is not None: raise ValueError('Invalid keyword arguments for adding grouping ' 'constraint. Cannot specify both a "select" ' 'value and a "max_select" value') if select is None and max_select is None and min_select is None: raise ValueError('Must specify a sensor selection limit for the ' 'grouping constraint.') gconlist = self._model.find_component('_groupingconlist') if gconlist is None: self._model._groupingconlist = pe.ConstraintList() gconlist = self._model._groupingconlist # Check to make sure all sensors are valid and build sum expression sensor_sum = sum(self._model.y[i] for i in sensor_list) if select is not None: # Select exactly 'select' sensors from sensor_list if select < 0: raise ValueError('Cannot select a negative number of sensors') gconlist.add(sensor_sum == select) elif min_select is not None and max_select is not None: # Select between min_select and max_select sensors from # sensor_list if (min_select < 0) or (max_select < 0): raise ValueError('Cannot select a negative number of sensors') if min_select > max_select: raise ValueError('min_select must be less than max_select') #gconlist.add(min_select <= sensor_sum <= max_select) # Chained inequalities are deprecated gconlist.add(aml.inequality(min_select, sensor_sum, max_select)) elif min_select is not None: # Select at least min_select sensors from sensor list if min_select < 0: raise ValueError('Cannot select a negative number of sensors') gconlist.add(min_select <= sensor_sum) else: # Select at most max_select sensors from sensor list if max_select < 0: raise ValueError('Cannot select a negative number of sensors') gconlist.add(sensor_sum <= max_select) # Any changes to the model require re-solving self._solved = False
#constraints model.C1 = pyo.ConstraintList() for t in model.setT: model.C1.add(expr=2 * x[2, t] - 8 * x[3, t] <= 0) model.C2 = pyo.ConstraintList() for t in range(3, T + 1): model.C2.add(expr=x[2, t] - 2 * x[3, t - 2] + x[4, t] >= 1) model.C3 = pyo.ConstraintList() for t in model.setT: model.C3.add(expr=sum([x[m, t] for m in range(1, M + 1)]) <= 50) model.C4 = pyo.ConstraintList() for t in range(2, T + 1): model.C4.add( expr=x[1, t] + x[2, t - 1] + x[3, t] + x[4, t] <= model.LimProd) model.C5 = pyo.ConstraintList() for m in range(1, M + 1): for t in model.setT: model.C5.add(pyo.inequality(0, x[m, t], model.LimProd)) #solve opt = SolverFactory('gurobi') opt.options['MIPgap'] = 0 opt.options['TimeLimit'] = 10 results = opt.solve(model, tee=True) print(pyo.value(model.obj))
def G3_rule(model): valueG3 = sum(model.x[i] * 100 for i in model.G3) return environ.inequality(model.minG3, valueG3, model.maxG3)
model.vFalse)) == model.pTrue) # x > 0 model.c12 = Constraint(expr=Expr_if( IF=(model.vN1 * 10.0 > 0), THEN=(model.vTrue), ELSE=( model.vFalse)) == model.pFalse) model.c13 = Constraint(expr=Expr_if( IF=(model.v0 * 10.0 > 0), THEN=(model.vTrue), ELSE=( model.vFalse)) == model.pFalse) model.c14 = Constraint(expr=Expr_if( IF=(model.vP1 * 10.0 > 0), THEN=(model.vTrue), ELSE=( model.vFalse)) == model.pTrue) # -1 <= x <= 1 model.c15 = Constraint(expr=Expr_if( IF=inequality(-1, model.vN2, 1), THEN=(model.vTrue), ELSE=( model.vFalse)) == model.pFalse) model.c16 = Constraint(expr=Expr_if(IF=inequality(-1 * model.vP1, model.vN1, 1), THEN=(model.vTrue), ELSE=(model.vFalse)) == model.pTrue) model.c17 = Constraint(expr=Expr_if(IF=inequality(-1 * model.vP1**2, model.v0, 1), THEN=(model.vTrue), ELSE=(model.vFalse)) == model.pTrue) model.c18 = Constraint(expr=Expr_if(IF=inequality(model.vN1, model.vP1, 1), THEN=(model.vTrue), ELSE=(model.vFalse)) == model.pTrue) model.c19 = Constraint(expr=Expr_if( IF=inequality(-1, model.vP2, 1), THEN=(model.vTrue), ELSE=( model.vFalse)) == model.pFalse)
def relax(model, descend_into=None, in_place=False, use_fbbt=True, fbbt_options=None): """ Create a convex relaxation of the model. Parameters ---------- model: pyomo.core.base.block._BlockData or pyomo.core.base.PyomoModel.ConcreteModel The model or block to be relaxed descend_into: type or tuple of type, optional The types of pyomo components that should be checked for constraints to be relaxed. The default is (Block, Disjunct). in_place: bool, optional If False (default=False), model will be cloned, and the clone will be relaxed. If True, then model will be modified in place. use_fbbt: bool, optional If True (default=True), then FBBT will be used to tighten variable bounds. If False, FBBT will not be used. fbbt_options: dict, optional The options to pass to the call to fbbt. See pyomo.contrib.fbbt.fbbt.fbbt for details. Returns ------- m: pyomo.core.base.block._BlockData or pyomo.core.base.PyomoModel.ConcreteModel The relaxed model """ """ For now, we will use FBBT both before relaxing the model and after relaxing the model. The reason we need to do it before relaxing the model is that the variable bounds will affect the structure of the relaxation. For example, if we need to relax x**3 and x >= 0, then we know x**3 is convex, and we can relax it as a convex, univariate function. However, if x can be positive or negative, then x**3 is neither convex nor concave. In this case, we relax it by reformulating it as x * x**2. The hope is that performing FBBT before relaxing the model will help identify things like x >= 0 and therefore x**3 is convex. The correct way to do this is to update the relaxation classes so that the original expression is known, and the best relaxation can be used anytime the variable bounds are updated. For example, suppose the model is relaxed and, only after OBBT is performed, we find out x >= 0. We should be able to easily update the relaxation so that x**3 is then relaxed as a convex univariate function. The reason FBBT needs to be performed after relaxing the model is that we want to make sure that all of the auxilliary variables introduced get tightened bounds. The correct way to handle this is to perform FBBT with the original model with suspect, which forms a DAG. Each auxilliary variable introduced in the relaxed model corresponds to a node in the DAG. If we use suspect, then we can easily update the bounds of the auxilliary variables without performing FBBT a second time. """ if not in_place: m = model.clone() else: m = model if fbbt_options is None: fbbt_options = dict() if use_fbbt: fbbt(m, **fbbt_options) if descend_into is None: descend_into = (pe.Block, Disjunct) aux_var_map = dict() counter_dict = dict() degree_map = ComponentMap() for c in nonrelaxation_component_data_objects(m, ctype=Constraint, active=True, descend_into=descend_into, sort=True): body_degree = polynomial_degree(c.body) if body_degree is not None: if body_degree <= 1: continue if c.lower is not None and c.upper is not None: relaxation_side = RelaxationSide.BOTH elif c.lower is not None: relaxation_side = RelaxationSide.OVER elif c.upper is not None: relaxation_side = RelaxationSide.UNDER else: raise ValueError('Encountered a constraint without a lower or an upper bound: ' + str(c)) parent_block = c.parent_block() relaxation_side_map = ComponentMap() relaxation_side_map[c.body] = relaxation_side if parent_block in counter_dict: counter = counter_dict[parent_block] else: parent_block.relaxations = pe.Block() parent_block.aux_vars = pe.VarList() parent_block.aux_cons = pe.ConstraintList() counter = RelaxationCounter() counter_dict[parent_block] = counter new_body = _relax_expr(expr=c.body, aux_var_map=aux_var_map, parent_block=parent_block, relaxation_side_map=relaxation_side_map, counter=counter, degree_map=degree_map) lb = c.lower ub = c.upper parent_block.aux_cons.add(pe.inequality(lb, new_body, ub)) parent_component = c.parent_component() if parent_component.is_indexed(): del parent_component[c.index()] else: parent_block.del_component(c) for c in nonrelaxation_component_data_objects(m, ctype=pe.Objective, active=True, descend_into=descend_into, sort=True): degree = polynomial_degree(c.expr) if degree is not None: if degree <= 1: continue if c.sense == pe.minimize: relaxation_side = RelaxationSide.UNDER elif c.sense == pe.maximize: relaxation_side = RelaxationSide.OVER else: raise ValueError('Encountered an objective with an unrecognized sense: ' + str(c)) parent_block = c.parent_block() relaxation_side_map = ComponentMap() relaxation_side_map[c.expr] = relaxation_side if parent_block in counter_dict: counter = counter_dict[parent_block] else: parent_block.relaxations = pe.Block() parent_block.aux_vars = pe.VarList() parent_block.aux_cons = pe.ConstraintList() counter = RelaxationCounter() counter_dict[parent_block] = counter if not hasattr(parent_block, 'aux_objectives'): parent_block.aux_objectives = pe.ObjectiveList() new_body = _relax_expr(expr=c.expr, aux_var_map=aux_var_map, parent_block=parent_block, relaxation_side_map=relaxation_side_map, counter=counter, degree_map=degree_map) sense = c.sense parent_block.aux_objectives.add(new_body, sense=sense) parent_component = c.parent_component() if parent_component.is_indexed(): del parent_component[c.index()] else: parent_block.del_component(c) if use_fbbt: for _aux_var, relaxation in aux_var_map.values(): relaxation.rebuild(build_nonlinear_constraint=True) tmp_fbbt_options = dict(fbbt_options) tmp_fbbt_options['deactivate_satisfied_constraints'] = False fbbt(m, **tmp_fbbt_options) for _aux_var, relaxation in aux_var_map.values(): relaxation.use_linear_relaxation = True relaxation.rebuild() else: for _aux_var, relaxation in aux_var_map.values(): relaxation.use_linear_relaxation = True relaxation.rebuild() return m