I constructed an abstract model in Pyomo and it worked well.
However, when I try to use a dictionary to instantiate the abstract model, I got the following errors "ERROR: Rule failed when generating expression for objective value: RuntimeError: Cannot iterate over abstract Set 'I' before it has been constructed (initialized)."
To be specific, here's the issue:
from pyomo.environ import *
model = AbstractModel()
model.D = Set()
model.I = Set()
model.w = Param(model.D)
model.S_0 = Param(model.D)
model.x = Var(real_model.I, model.D)
def sum_cubic(m):
return sum(w[j]*(m.x[i][j]-m.S_0[j])**3 for i in model.I for j in model.D)
model.value = Objective(rule = sum_cubic, sense = maximize)
model.pprint()
The above code runs just fine. But errors are given when I add the following codes right after it where names and S_0 are predefined dictionaries:
data = {None:{
'D':{None: names},
'I':{None: list(range(1,4))},
'w':[0.3,0.3,0.4],
'S_0':S_0,
}
}
real_model = model.create_instance(data)
ERROR: Rule failed when generating expression for objective value: RuntimeError: Cannot iterate over abstract Set 'I' before it has been constructed (initialized). ERROR: Constructing component 'value' from data=None failed: RuntimeError: Cannot iterate over abstract Set 'I' before it has been constructed (initialized).
Could anyone help me with that? Thanks.
You have a couple things biting you here...
m.
and model.
in your function, where you should be using m.
because that is the self-referencing parameter of your function signaturem.x
incorrectly. It should be tuple-indexed (see mine)Good luck!
from pyomo.environ import *
model = AbstractModel()
model.D = Set()
model.I = Set()
model.w = Param(model.D)
model.S_0 = Param(model.D)
model.x = Var(model.I, model.D)
def sum_cubic(m):
return sum(m.w[j]*(m.x[i, j]-m.S_0[j])**3 for i in m.I for j in m.D)
model.value = Objective(rule = sum_cubic, sense = maximize)
model.pprint()
names=['a', 'b', 'c']
data = { None:{
'D': {None: names},
'I': {None: [1, 2, 3]},
'w': {'a': 0.4, 'b': 0.3, 'c': 0.2},
'S_0': {'a': 1.0, 'b': 2.0, 'c': 3.0} }
}
real_model = model.create_instance(data)