Given the following trivial model:
model.WEEKS = Set(initialize = [1,2,3])
model.PRODS = Set(initialize = ['Q24','J24','F24'])
model.volume = Var(model.WEEKS,model.PRODS, within = NonNegativeIntegers)
I'd like to set varying bounds for each permutation in model.volume
depending on the initial character of the second index. Currently, I have achieved this by applying the following constraints to specified subsets:
# create subsets
Q_PRODS = Set(within = model.WEEKS * model.PRODS, initialize = [x for x in model.volume if x[1][0]=='Q'])
M_PRODS = Set(within = model.WEEKS * model.PRODS, initialize = [x for x in model.volume if x[1][0]!='Q'])
#define functions
def c1(model, i,j):
return (25, model.volume[i,j], 60)
model.c1 = Constraint(Q_PRODS, rule = c1)
def c2(model, i,j):
return (40, model.volume[i,j], 75)
model.c2 = Constraint(M_PRODS, rule = c2)
Which correctly outputs the following:
2 Constraint Declarations
c1 : Size=3, Index=c1_index, Active=True
Key : Lower : Body : Upper : Active
(1, 'Q24') : 25.0 : volume[1,Q24] : 60.0 : True
(2, 'Q24') : 25.0 : volume[2,Q24] : 60.0 : True
(3, 'Q24') : 25.0 : volume[3,Q24] : 60.0 : True
c2 : Size=6, Index=c2_index, Active=True
Key : Lower : Body : Upper : Active
(1, 'F24') : 40.0 : volume[1,F24] : 75.0 : True
(1, 'J24') : 40.0 : volume[1,J24] : 75.0 : True
(2, 'F24') : 40.0 : volume[2,F24] : 75.0 : True
(2, 'J24') : 40.0 : volume[2,J24] : 75.0 : True
(3, 'F24') : 40.0 : volume[3,F24] : 75.0 : True
(3, 'J24') : 40.0 : volume[3,J24] : 75.0 : True
However, this seems a little clumsy and I wondered if there is more efficient method that would achieve the same ends? For example, by defining a rule to pass during the creation of model.volume
?
You can use a callable to provide limits, if desired. For most Pyomo
constructs, it must catch the indexing variables and also have a self-reference to the model. There are other examples in the dox.
import pyomo.environ as pyo
m = pyo.ConcreteModel()
m.I = pyo.Set(initialize=[1, 2, 3, 4])
def v_limits(m, i):
if i%2==0:
return (10, 20)
return (8, 9)
m.X = pyo.Var(m.I, bounds=v_limits)
m.pprint()