I have a question about referecing set in Pyomo objectives. Basically I have 2 options and I do not understand why one of it works whereas the other yields an error. Here you see them:

model.set_timeslots = pyo.RangeSet(0,95)

def ObjectiveRule (model):
    return sum(model.variable_heatGeneration[t]  for t in model.set_timeslots)

model.objective_costs = pyo.Objective( rule=ObjectiveRule, sense =pyo.minimize)

#Option 2
def ObjectiveRule_2 (model, t):
    return sum(model.variable_heatGeneration[t])

model.objective_costs = pyo.Objective(model.set_timeslots, rule=ObjectiveRule_2, sense =pyo.minimize)

The second options leads to the error

TypeError: '_GeneralVarData' object is not iterable

Can you tell me what the difference is and why the second option does not work?

Reminder: Can nobody tell me what the difference is?


1 Answer 1


The first option makes sense to me : you are returning a sum such as : $$ \sum_{t \in T} h_t $$

where $h_t$ represents your variable_heatGeneration and $T$ your set_timeslots.

The second option I do not understand and am not surprised an error is raised. You are returning the sum of a constant $h_t$. I believe the error

TypeError: '_GeneralVarData' object is not iterable

is raised because the object model.variable_heatGeneration[t] is constant and not an iterable object such as list. It is trying to sum over a constant which makes no sense.

In a sum, you need an iterable object, for example :

sum(x for x in range(10)) # sum over an iterable
sum(x for x in L) # if L is a list 
sum([x for x in range(10)]) # sum over a list

In option 2 you are doing something like

sum(x) # where x is a constant
# or 

To get rid of this specific error, try removing the sum :

#Option 2
def ObjectiveRule_2 (model, t):
    return model.variable_heatGeneration[t]

Note that this will probably create another error somewhere else, and it will not model the wanted cost function. Sticking with option $1$ is a better idea.

  • $\begingroup$ Thanks Kuifje for your answer. You wrote "model.variable_heatGeneration[t] is constant" --> This is not true. The variable_heatGeneration is a decision variable that should be determined by the solver. It depends on the set t and has one value for every t. This is why we can in fact sum it up variable_heatGeneration [1] + variable_heatGeneration [2] + ... variable_heatGeneration [n] $\endgroup$
    – PeterBe
    Mar 2, 2021 at 15:02
  • $\begingroup$ You wrote "To get rid of this specific error, try removing the sum "--> This does not make sense at all because I do want to calculate the sum in the objective function. $\endgroup$
    – PeterBe
    Mar 2, 2021 at 15:03
  • $\begingroup$ I didn't say it would make any sense :) I said it would get rid of the specific error that is mentioned, and that indeed it does not model the wanted cost function. $\endgroup$
    – Kuifje
    Mar 2, 2021 at 15:11
  • $\begingroup$ "model.variable_heatGeneration[t]" is a variable. But for a given $t$ (input of ObjectiveRule_2), it will be a constant (the value of the variable). In all cases it is not an iterable object so you cannot sum over it, when $t$ is fixed. $\endgroup$
    – Kuifje
    Mar 2, 2021 at 15:14
  • 1
    $\begingroup$ Thanks for your answer and help Kuifje. I accepted and upvoted your answer. Further, I awarded the bounty to you. I really appreciate your help. $\endgroup$
    – PeterBe
    Mar 4, 2021 at 8:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.