以不同方式初始化Params给了我相同的属性错误

问题描述 投票:2回答:2

我正在尝试使用pyomo来解决二次方案。我的模型如下。我将在后期阶段添加更多约束和目标。

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'

如果我尝试使用列表/数组来初始化参数,则错误完全相同。错误的唯一区别是错误地将'dict'更改为'list / numpy.ndarray'。我不确定我做错了什么。

另外,我确实看了question here.这就是为什么将数组转换为字典。

python pyomo
2个回答
2
投票

如ycx所述,Pyomo中存在一个错误。如果将对象传递给Param,则会尝试将其用作表达式对象,而不是迭代它并使用值来初始化param。

您需要做的是更改代码以使用返回输入正确值的函数。请参阅代码文档中的示例:

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)

0
投票

继续我之前的评论:

github.com/Pyomo/pyomo/issues/611。您可能必须进入pyomo的源代码以实现Param()函数的返回float(np.random.rand(1)),以便在等待库创建者更新它时进行修复

你将不得不使用你的IDE并检查Param()函数(我使用Spyder,所以它是mouse highlight Param > mouse right-click > mouse click 'Go to definition'。它应该打开一个.py文件,你将能够从那里编辑源代码插入上面的返回声明并解决问题。

© www.soinside.com 2019 - 2024. All rights reserved.