提问者:小点点

TypeError PYOMO:基于数据帧定义约束


对于一个优化问题,我试图在PYOMO中定义一个约束,其中约束表达式包含来自pandas数据帧的一些特定值。

我会尽量用简洁的方式解释我的问题。

以下是进口商品。

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), initialize = 0.9)
model.t1 = Var(bounds=(0.1,0.3))

目标函数如下所示:

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

为了构造约束表达式,我使用了数据帧中的一些值。

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

当前想法:

我将df中的一些值分配给变量,以便在约束表达式中使用(如下所示)。

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

v1和v2的唯一用途是向约束表达式输入值。这与优化模型无关。

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

但是我在执行这个想法时犯了以下错误

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

据我所知,python将v1和v2视为“浮点”和模型。d1被视为“非类型”。我试图通过向变量模型添加initialize来运行模型。d1。但它似乎仍然是“非类型”。

有人能帮我解决这个问题吗?

事先非常感谢。

PS:模型。d1。display()提供以下输出。

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

共1个答案

匿名用户

因此,您可能偶然发现了一个小错误,即当pyomo变量是单例时,pyomo如何与Numpy值交互......我认为这种情况不会经常出现,因为在处理索引的pyomo变量时,问题不会暴露自己,这是迄今为止大多数情况。您的是非索引单例。

首先,让我们让您的模型工作。将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()

可疑的虫子。。。

根据我的理解,这两项都应该执行。我几乎从来没有处理过w/单例变量(没有索引),所以这里可能还有其他事情正在进行。我会把它作为一个bug提交给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...