简体   繁体   English

TypeError PYOMO:基于 pandas dataframe 定义约束

[英]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.对于优化问题,我试图在 PYOMO 中定义一个约束,其中约束表达式包括来自 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:物镜 function 如下:

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

To formulate a constraint expression, I am using some values from a DataFrame.为了制定约束表达式,我使用了 DataFrame 中的一些值。

The DataFrame would look like this: DataFrame 看起来像这样:

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).我将 df 中的一些值分配给变量,以便在约束表达式中使用(如下所示)。

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. v1 和 v2 的唯一目的是为约束表达式输入值。 It has nothing to do with the optimization model.与优化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'.据我了解,python 将 v1 和 v2 视为“float”,而 model.d1 被视为“NoneType”。 I tried to run the model by adding initialize to the variable model.d1.我尝试通过将initialize添加到变量 model.d1 来运行 model。 But still it seems 'NoneType'.但它似乎仍然是“NoneType”。

Can someone please help me to solve this?有人可以帮我解决这个问题吗?

Thank you very much in advance.非常感谢您提前。

PS: model.d1.display() gives following output. PS: model.d1.display()给出以下 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.因此,当pyomo变量为numpy pyomo交互的一个小错误……我认为这不会经常出现,因为在处理索引pyomo变量时问题不会暴露出来,这是目前大多数情况。 Yours are non-indexed singletons.你的是非索引单例。

First, let's get your model working.首先,让您的 model 工作。 Convert the values coming out of your df into floats and this works fine.将来自您的df的值转换为浮点数,这可以正常工作。

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...疑似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.我几乎从不处理 singleton 变量(未编入索引),所以这里可能还有其他事情要做。 I'll try to submit this to pyomo folks as a bug and see what comes of it.我会尝试将此作为错误提交给 pyomo 人,看看会发生什么。

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...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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