以不同方式初始化参数给我相同的属性错误
Initializing Params in Different ways gives me the same Attribute Error
我正在尝试使用 pyomo 求解二次程序。我的模型如下。我将在稍后阶段添加更多约束和 objective。
from pyomo.environ import *
model = ConcreteModel()
model.IDX1 = range(96)
model.IDX2 = range(192)
model.IDX3 = range(49)
# Variables
model.x = Var(model.IDX1)
b2 = main_power2.iloc[[0]]
b2 = np.append([0], np.asarray(b2))
model.H_py = Param(model.IDX1, initialize = arrtodict(Hp)) # Hp: 96*96
model.A1_py = Param(model.IDX2, initialize = arrtodict(A1l)) # A1l: 192 * 96
model.b1_py = Param(model.IDX2, initialize = arrtodict(b1)) # 192*1
model.A2_py = Param(model.IDX3, initialize = arrtodict(A2)) # 49 * 96
model.b2_py = Param(model.IDX3, initialize = arrtodict(b2)) # 49,1
def inequality_rule(model,i): # i = IDX2
return sum( model.A1_py[i][j] * model.x[j] for j in model.IDX1 ) <= model.b1_py[i]
model.c1 = Constraint (model.IDX2, rule = inequality_rule )
其中 arrtodict 是一个将数组 (1-D, 2-D) 转换为字典的函数,如下所示。将其转换为字典的全部意义在于,如果我没有记错的话,参数初始化是使用字典完成的。
def arrtodict(your_array):
your_array = your_array.tolist()
dict_data = {key: value for key, value in enumerate(your_array)}
if type(dict_data[0]) is list:
for key, value in dict_data.items():
dict_data[key] = {k: v for k, v in enumerate(value)}
elif type(dict_data[0]) is (float or int):
pass
else:
print ('Check Your data')
return dict_data
出于某种原因,我不断收到以下错误:
line 3530, in _generate_relational_expression
if not (rhs.__class__ in native_types or rhs.is_expression_type()):
AttributeError: 'dict' object has no attribute 'is_expression_type'
如果我尝试使用 list/array 初始化参数,错误完全相同。错误的唯一区别是 'dict' 错误地更改为 'list/numpy.ndarray'。我不确定我做错了什么。
此外,我确实查看了 question here.这就是将数组转换为字典的原因。
正如 ycx 所指出的,Pyomo 中存在一个错误。如果将对象传递给 Param initialize,它会尝试将其用作表达式对象,而不是遍历它并使用值来初始化参数。
您需要做的是更改您的代码以使用 returns 正确输入值的函数。请参阅代码文档中的示例:
https://github.com/Pyomo/pyomo/blob/master/examples/pyomo/tutorials/param.py
# A parameter can be constructed with the _initialize_ option, which is a
# function that accepts the parameter indices and model and returns the value
# of that parameter element:
#
def W_init(model, i, j):
#
# Create the value of model.W[i,j]
#
return i*j
model.W = Param(model.A, model.B, initialize=W_init)
我之前评论的延续:
github.com/Pyomo/pyomo/issues/611. You might have to go into the
source code of pyomo to implement return float(np.random.rand(1)) for
Param() function in order to fix it while waiting for the library
creator to update it
你必须使用你的 IDE 并检查 Param()
函数(我使用的是 Spyder,所以它是 mouse highlight Param > mouse right-click > mouse click 'Go to definition'
。它应该打开一个 .py
文件,您将能够从那里编辑源代码以插入上面的 return 语句并解决问题。
我正在尝试使用 pyomo 求解二次程序。我的模型如下。我将在稍后阶段添加更多约束和 objective。
from pyomo.environ import *
model = ConcreteModel()
model.IDX1 = range(96)
model.IDX2 = range(192)
model.IDX3 = range(49)
# Variables
model.x = Var(model.IDX1)
b2 = main_power2.iloc[[0]]
b2 = np.append([0], np.asarray(b2))
model.H_py = Param(model.IDX1, initialize = arrtodict(Hp)) # Hp: 96*96
model.A1_py = Param(model.IDX2, initialize = arrtodict(A1l)) # A1l: 192 * 96
model.b1_py = Param(model.IDX2, initialize = arrtodict(b1)) # 192*1
model.A2_py = Param(model.IDX3, initialize = arrtodict(A2)) # 49 * 96
model.b2_py = Param(model.IDX3, initialize = arrtodict(b2)) # 49,1
def inequality_rule(model,i): # i = IDX2
return sum( model.A1_py[i][j] * model.x[j] for j in model.IDX1 ) <= model.b1_py[i]
model.c1 = Constraint (model.IDX2, rule = inequality_rule )
其中 arrtodict 是一个将数组 (1-D, 2-D) 转换为字典的函数,如下所示。将其转换为字典的全部意义在于,如果我没有记错的话,参数初始化是使用字典完成的。
def arrtodict(your_array):
your_array = your_array.tolist()
dict_data = {key: value for key, value in enumerate(your_array)}
if type(dict_data[0]) is list:
for key, value in dict_data.items():
dict_data[key] = {k: v for k, v in enumerate(value)}
elif type(dict_data[0]) is (float or int):
pass
else:
print ('Check Your data')
return dict_data
出于某种原因,我不断收到以下错误:
line 3530, in _generate_relational_expression
if not (rhs.__class__ in native_types or rhs.is_expression_type()):
AttributeError: 'dict' object has no attribute 'is_expression_type'
如果我尝试使用 list/array 初始化参数,错误完全相同。错误的唯一区别是 'dict' 错误地更改为 'list/numpy.ndarray'。我不确定我做错了什么。
此外,我确实查看了 question here.这就是将数组转换为字典的原因。
正如 ycx 所指出的,Pyomo 中存在一个错误。如果将对象传递给 Param initialize,它会尝试将其用作表达式对象,而不是遍历它并使用值来初始化参数。
您需要做的是更改您的代码以使用 returns 正确输入值的函数。请参阅代码文档中的示例:
https://github.com/Pyomo/pyomo/blob/master/examples/pyomo/tutorials/param.py
# A parameter can be constructed with the _initialize_ option, which is a
# function that accepts the parameter indices and model and returns the value
# of that parameter element:
#
def W_init(model, i, j):
#
# Create the value of model.W[i,j]
#
return i*j
model.W = Param(model.A, model.B, initialize=W_init)
我之前评论的延续:
github.com/Pyomo/pyomo/issues/611. You might have to go into the source code of pyomo to implement return float(np.random.rand(1)) for Param() function in order to fix it while waiting for the library creator to update it
你必须使用你的 IDE 并检查 Param()
函数(我使用的是 Spyder,所以它是 mouse highlight Param > mouse right-click > mouse click 'Go to definition'
。它应该打开一个 .py
文件,您将能够从那里编辑源代码以插入上面的 return 语句并解决问题。