Search code examples
pythonscriptingmathematical-optimizationpyomo

How to create multiple objectives iteratively in Pyomo AbstractModel?


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.


Solution

  • 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.