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?


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 14 hours ago
  • $\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 14 hours ago
  • $\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 14 hours ago
  • $\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 14 hours ago
  • $\begingroup$ Thanks for your answer and effort Kuifje. I really appreciate it. I do not understand why t is fixed in the scond option. I pass all the sets (model.set_timeslots) to the ObjectiveRule_2 (model, t) function. The variable model.variable_heatGeneration[t] depends on t and I just want to build the sum over all ts $\endgroup$ – PeterBe 12 hours ago

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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