TypeError: object of type 'gurobipy.QuadExpr' has no len()
AnsweredHey there!
I am currently building a model that analyses power flows for a system consisting of a grid connection, demand, production and storage in the form of a battery. Im am currently trying to add taxes associated with power bought from the grid. In contrast to prices which may fluctuate over time, taxes fluctuate over the amount used over the year.
I have tried numerous ways to add this layer to the model, but i cannot get it working. My latest attempt is the following: there are two variables (Energy From Grid & Taxes) + (a bunch wrote as a variable but are actually constant to overcome errors). The energy from grid works perfectly, yet the taxes I cannot get it working:
m.addConstrs(taxes[t] == tax1[t] + tax2[t] + tax3[t] for t in range (T))
m.addConstrs(tax1[t] == gp.min_(energy_from_grid[t]*tax_price1[t], step1[t] * tax_price1[t]) for t in range (T))
m.addConstrs(tax2[t] == gp.min_(gp.max_((energy_from_grid[t] - step1[t])*tax_price2[t], 0), step2[t]*tax_price2[t]) for t in range (T))
m.addConstrs(tax3[t] == gp.max_((energy_from_grid[t] - step3[t]) * tax_price3[t], 0) for t in range (T))
The steps indicate from what total amount of energy bought from the grid a a certain tax level exists. The tax price is the corresponding tax price for that step. I wrote the steps/tax prices as variables (and added them as such) since I got errors such as "supported operand type(s) for *: 'tupledict' and 'float'". These steps and tax prices are actually constant values, so the model is currently more complex than it has to be. But to overcome these errors I splitted the tax layers into three variables and made all parameters variables as well. Yet I currently get the following error:
"TypeError: object of type 'gurobipy.QuadExpr' has no len()"
The problem I am trying to solve feels rather simple, but I cannot get it working. Which is why I wrote this ticket, hoping you might see what I do wrong/could guide me in the right direction.
Thanks in advance and happy hollidays.
Regards,
Johan
-
Official comment
This post is more than three years old. Some information may not be up to date. For current information, please check the Gurobi Documentation or Knowledge Base. If you need more help, please create a new post in the community forum. Or why not try our AI Gurobot?. -
Hi Johan,
The min_ and max_ function take only single variables and constants as input. This mean that the term
gp.max_((energy_from_grid[t] - step1[t])*tax_price2[t], 0)
will result in an error. To use the max_ function, you have to introduce an auxiliary variable and equality and pass it to the max_ function as
auxVar1 = m.addVars(T,lb=-GRB.INFINITY, vtype=GRB.CONTINUOUS, name="auxVar1")
m.addConstrs( (auxVar1[t] == (energy_from_grid[t] - step1[t])*tax_price2[t]) for t in range(T), name="auxConstr)
auxVar2 = m.addVars(T,lb=-GRB.INFINITY, vtype=GRB.CONTINUOUS, name="auxVar2")
m.addConstrs( (auxVar2[t] = gp.max_(auxVar1[t], constant=0) for t in range(T)))The same applies to the min_ function. If this does not resolve the issue, could you please post a minimal reproducible example.
Best regards,
Jaromił0 -
Hi Jaromil,
Thank you for your answer, and I think this is precicely the solution I am looking for. However, I do encounter some difficulties in applying. I made these two variables:
auxVar1 = m.addVars(T,lb=-10000, name="auxVar1")
auxVar2 = m.addVars(T,lb=-10000, name="auxVar2")I couldn't specify the GRB.INFINITY/GRB.CONTINOUS because then it states name "GRB" is not defined. I imported Gurobi as gp, so I also tried gp.INFINITY. Then it stated: module 'gurobipy' has no attribute 'INFINITY'. Therefore, I chose a manual lower bound, just for now.
I added the following constrains, and the model can run now.
m.addConstrs(auxVar1[t] == energy_from_grid[t]*el_tax1 for t in range(T))
m.addConstrs(auxVar2[t] == gp.min_(auxVar1[t], constant=10000*el_tax1) for t in range(T))They also provide the right answers, uptill the point that the constant value (which is aprroximately) 1250 ie met, where auxVar2 should be capped at. So it seems that the min_ function is not properly working yet, do you perhaps know what could be the cause of this?
Thanks a lot for your help!
Johan
0 -
ps: I managed to solve the GRB values, so they are now defined as:
auxVar1 = m.addVars(T,lb=-GRB.INFINITY, vtype=GRB.CONTINUOUS, name="auxVar1")
auxVar2 = m.addVars(T,lb=-GRB.INFINITY, vtype=GRB.CONTINUOUS, name="auxVar2")However, the same problem arises where auxVar2 does not take the proper min_ value of auxVar2 & the constant.
0 -
Hi Johan,
In order to use the GRB namespace you have to either import it or access it via the gurobipy module
import gurobipy as gp
from gurobipy import GRBor
import gurobipy as gp
[...]
m.addVar(lb=-gp.GRB.INFINITY,vtype=gp.GRB.CONTINUOUS,name="auxVar")I don't fully understand your second point about the min_ function being capped at 1250. Is it possible that the value of auxVar1 gets below 1250? Could you elaborate more on this issue?
Best regards,
Jaromił0 -
Hi Jaromil,
Appologies for the unclearity.
So what I currently have:
My variables:
auxVar1 = m.addVars(T,lb=-GRB.INFINITY, vtype=GRB.CONTINUOUS, name="auxVar1")
auxVar2 = m.addVars(T,lb=-GRB.INFINITY, vtype=GRB.CONTINUOUS, name="auxVar2")My constraints:
m.addConstrs(auxVar1[t] == energy_from_grid[t]*el_tax1 for t in range(T))
m.addConstrs( (auxVar2[t] == gp.min_(auxVar1[t], constant=1250) for t in range(T)))Following the constraints, the main goal that I wish to achieve here is that auxVar2 chooses the lowest value, so when energy_from_grid[t]*el_tax1 < 1250, it should pick 1250. If energy_from_grid[t]*el_tax1>1250 it should pick 1250. Currently, it always picks energy_from_grid[t]*el_tax1 eventhough the value exceeds 1250.
In the picture below, these values are illustrated.
So my question to you is, do you have an idea why the min_ function does not take the actual min value, but always picks auxVar1?
0 -
Hi Johan,
In your solution it is auxVar1 = 1247.2 so \(\min(1247.2, 1250) = 1247.2\) but I also see \(\min(1252.9, 1250) = 1252.9\). You also stated
the main goal that I wish to achieve here is that auxVar2 chooses the lowest value, so when energy_from_grid[t]*el_tax1 < 1250, it should pick 1250. If energy_from_grid[t]*el_tax1>1250 it should pick 1250.
So you wish that auxVar2 equals 1250 in both cases? I assume it is a typo.
Now I understand the issue, you mean that some of the AuxVar values are correct and for some it does not work? Are you sure that the data frame you have shown is correct? Could you try to construct a minimal working example where this happens?
Best regards,
Jaromił0 -
Hi Jaromil,
What I tried to visualize in the screen shot, is that until jan 10, the code does what it should do. Since auxVar2 picks the lowest value of the variable and the constant, namely everything below 1250. However, in the timeslot that follows auxVar1 becomes larger than 1250, namely 1252.91, then the constraint should pick 1250 instead, however it keeps selecting the same value as auxVar1.
I cannot figure out what I formulated wrong, I hope this clarifies the issue I am currently encountering.
Regards,
Johan
0 -
Hi Johan,
Can you try to isolate the issue by reducing the size of your model? Could you double check the output in the data frame? Are you reading the correct auxiliary variable data?
Best regards,
Jaromił0 -
Dear Jaromil,
First of all I would like to state I am very pleased by the why you are helping me, world class! Can I leave a review somewhere to state this satisfaction?
Secondly, I double checked everything. I will enclose my variable list and the way the Dataframe is constructed, but I simply cannot find the mistake... Could it perhaps have to do with that Gurobi reads either the constant or the auxVar1 as a different type of variable, thus it simply doesn't know if its < or not?
Setting my variables:

Getting the variables out of Gurobi:

The dataFrame B:
0 -
Hi Johan,
I opened a Request in our Support Portal to better investigate this issue. You should have received a corresponding email.
First of all I would like to state I am very pleased by the why you are helping me, world class! Can I leave a review somewhere to state this satisfaction?
Thank you for the kind words. Unfortunately it is not possible yet to leave a review in our Community Forum but helping our users is the best motivation :)
Best regards,
Jaromił0 -
Thank you very much Jaromil!
Hoping the Support Portal can trace back what is going wrong.
You helped me enormously already.Happy hollidays!
Even though I cant leave an official review, you still get a 5/5 ;)
0 -
This issue has been resolved internally. The issue was caused by using an older Gurobi version. In version 9.1.2, the min constraints with a constant have to be introduced via
m.addConstrs( (auxVar2[t] == gp.min_(auxVar1[t], 1250) for t in range(T)))
instead of
m.addConstrs( (auxVar2[t] == gp.min_(auxVar1[t], constant=1250) for t in range(T)))
0
Post is closed for comments.
Comments
13 comments