简体   繁体   中英

TypeError PYOMO: Defining constraints based on pandas dataframe

For an optimization problem, I am trying to define a constraint in PYOMO, where the the constraint expression includes some specific values from a pandas DataFrame.

I will try to explain my problem in a concise way.

Following are the imports.

from pyomo.environ import *
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt 
from pyomo.opt import SolverFactory

model = ConcreteModel()

The following are the decision variables.

model.d1 = Var(bounds=(0.8,1.0), initialize = 0.9)
model.t1 = Var(bounds=(0.1,0.3))

The objective function is given below:

model.Total_weight = Objective(expr=  model.t1*model.d1, sense= minimize )

To formulate a constraint expression, I am using some values from a DataFrame.

The DataFrame would look like this:

r1 = [50.05,60.0,70]
r2 = [100,150,200]

df = pd.DataFrame([r1,r2])

        0      1    2
0   50.05   60.0   70
1  100.00  150.0  200

Current Idea:

I am assigning some of the values from the df to variables, in order to be used in the constraint expression (as shown below).

v1 = df.iloc[0, 1]
v2 = df.iloc[1,1]

The only purpose of v1 and v2 is to input value to the constraint expression. It has nothing to do with the optimization model.

model.C1 = Constraint(expr =  v1 +  v2 *model.d1 <= 2.1)

But I got the following error while executing this idea

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-9-a9a7f2887bcb> in <module>
----> 1 model.C1 = Constraint(expr = v1 +  v2 *model.d1)

TypeError: unsupported operand type(s) for *: 'float' and 'NoneType'

To my understanding, python considers v1 and v2 as 'float' and model.d1 is considered as 'NoneType'. I tried to run the model by adding initialize to the variable model.d1. But still it seems 'NoneType'.

Can someone please help me to solve this?

Thank you very much in advance.

PS: model.d1.display() gives following output.

d1 : Size=1, Index=None
    Key  : Lower : Value : Upper : Fixed : Stale : Domain
    None :   0.8 :   0.9 :   1.0 : False : False :  Reals

So you might have stumbled onto a small bug in how pyomo interacts with numpy values when the pyomo variable is a singleton.... I don't think this comes up too often as the problem does not expose itself when dealing with indexed pyomo variables, which is by far the majority case. Yours are non-indexed singletons.

First, let's get your model working. Convert the values coming out of your df into floats and this works fine.

from pyomo.environ import *
#import numpy as np
import pandas as pd
import matplotlib.pyplot as plt 
#from pyomo.opt import SolverFactory

model = ConcreteModel()

model.d1 = Var(bounds=(0.8,1.0), domain=NonNegativeReals)
model.t1 = Var(bounds=(0.1,0.3), domain=NonNegativeReals)

r1 = [50.05,60.0,70]
r2 = [100,150,200]

df = pd.DataFrame([r1,r2])

v1 = float(df.iloc[0, 1])   # NOTE the float() conversion
v2 = float(df.iloc[1, 1])   # NOTE the float() conversion

model.C1 = Constraint(expr=v1 + v2 * model.d1 <= 2.1)

model.pprint()

The suspected bug...

Both of these should execute by my understanding. I almost never deal w/ singleton variables (that are not indexed) so perhaps there is something else afoot here. I'll try to submit this to pyomo folks as a bug and see what comes of it.

from pyomo.environ import *
import numpy as np

c = np.float64(1.5)  # a numpy float like what comes out of a pd dataframe...

model_1 = ConcreteModel()

model_1.x = Var()

# a simple expression
e = c * model_1.x     # FAILS!  TypeError: unsupported operand type(s) for *: 'float' and 'NoneType'


model_2 = ConcreteModel()

model_2.S = Set(initialize = [1,])   # indexing set with 1 member

model_2.x = Var(model_2.S)

# same expression
e2 = c * model_2.x[1]  # Works fine...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM