Search code examples
pyomo

Pyomo and dynamic objective function creation


I want to iteratively add to a Pyomo objective function based upon rows in a pandas dataframe. I've created variables based upon the size of the dataframe:

model.A = Var(range(0,len(arc_decvars)), initialize=0,within=Integers,bounds=(0,5))

where arc_decvars is a list in the same order as the corresponding pandas dataframe series.

What I would like to do is create an objective function like this, but without having to specify the indices explicitly in the code:

model.ObjFcn = ( df.coefficient[0] * model.A[0] * ( 1- df.coefficient[0] * model.A[0]) ) + ( df.coefficient[1] * model.A[1] * ( 1- df.coefficient[1] * model.A[1]) +...+ ( df.coefficient[999] * model.A[999] * ( 1- df.coefficient[999] * model.A[999]) )

Any idea on how to do this?

---- Followup:

I am adding a series of constraints like this, one for each node:

def NodeA(model):
    k = sum(
        model.ArcVar[i] * node_arc_matrix[i,0]
        for i in model.ArcVar
            )
    return k ==  2*model.NodeVar[1]
model.NodeAConstraint=Constraint(rule=NodeA)

Where the 0-index in node_arc_matrix refers to the column corresponding to Node_A. Instead of creating a constriant for each node manually can I create constraints across both i (arcs) and j (nodes)?


Solution

  • Try using Python list comprehension into the summation formulation.

    Considering df.coefficient and model.A have arc_decvars as the domain and that arc_decvars is in a Pyomo Set, you can create your objective function this way:

    model.ObjFcn = sum(
        df.coefficient[i] * model.A[i] * ( 1- df.coefficient[i] * model.A[i])
        for i in model.arc_devcars
    )