我正在尝试使用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.这就是为什么将数组转换为字典。
如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)
继续我之前的评论:
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
文件,你将能够从那里编辑源代码插入上面的返回声明并解决问题。