I am trying to implement an AbstractModel
that looks to optimise iteratively multiple objective functions over the same feasible set.
Since I want to have the most transparency in the surrounding scripts, more precisely the one activating the different objective functions iteratively, I would like to contain all the objective functions in a single obj
attribute of the model. How should I go about doing that?
Since there are two types of objectives indexed over different sets, I attempted to create both types individually and then merge the two in an ObjectiveList
.
This would result in the following :
import pyomo.environ as pyo
model=pyo.AbstractModel()
model.i=pyo.Set(initialize=[1,2])
model.a=pyo.Set(initialize=[(1,2),(2,1)])
model.x=pyo.Var()
model.obj=pyo.ObjectiveList()
def obj_type1(model,i):
return x**2
obj_type1=pyo.Objective(model.i,rule=obj_type1)
for key, new_obj in obj_type1.items():
model.obj.add(new_obj)
def obj_type2(model,a):
return x+1
obj_type2=pyo.Objective(model.a,rule=obj_type2)
for key, new_obj in obj_type2.items():
model.obj.add(new_obj)
This is not working, since in the AbstractModel
, I cannot iterate over the individual objective containers.
You can do this in a rule:
def _obj(m, j):
if j < 3:
return m.x**2
else:
return m.x+1
m.obj = Objective([1,2,3,4], rule=_obj)
Just make sure to deactivate all but one objective before sending the model to a solver.