【问题标题】:How to split parameters in function of define with string?如何在用字符串定义的函数中拆分参数?
【发布时间】:2021-10-13 13:36:56
【问题描述】:

我需要做一个方程(除以 PI(i,s) 和 PJ(j,s))。这些参数有索引。
此代码是在 GAMS 中编写的,而在 pyomo 中,集合(带字符串)的操作是不同的。 我不知道如何解决这个问题。

我的代码:

HN_model=ConcreteModel()

i=['U4241', 'U241', 'U241A']
    HN_model.i=Set(initialize=[(len(i))])
    j=['U4283', 'U283', 'U283A', 'U3283', 'U2280', 'U1280']
    HN_model.j=Set(initialize=[(len(j))])
    k=['PSA4241', 'PSA241', 'PSA241A', 'PSA3241']
    HN_model.k=Set(initialize=[(len(k))])
    s=[1]
    HN_model.s=Set(initialize=range(len(s)))

HN_model.ij=Set(within=HN_model.i*HN_model.j, initialize = [(i,j) for i in HN_model.i for j in HN_model.j])

HN_model.T=Param(initialize=300.00)
HN_model.Cp_hidrogenio=Param(initialize=29.00)
HN_model.Cp_metano=Param(initialize=50.00)
HN_model.Cp_medio=Param(initialize=35.00)
HN_model.ef=Param(initialize=0.6)
HN_model.T0=Param(initialize=288.7)
HN_model.P0=Param(initialize=1.00)
HN_model.R=Param(initialize=8.314,)
HN_model.PPi=Param(initialize=5.5)
HN_model.gama=Expression(expr=HN_model.Cp_medio/(HN_model.Cp_medio-HN_model.R))

PJ={}
PJ['U4283',1]=137;
PJ['U283',1]=88.5;
PJ['U283A',1]=88.5;
PJ['U3283',1]=30;
PJ['U2280',1]=30;
PJ['U1280',1]=30;
HN_model.PJ=Param(HN_model.j,HN_model.s,initialize=[PJ])

PI={}
PI['U4241',1]=21.3;
PI['U241',1]=21.1;
PI['U241A',1]=21.1;
HN_model.PI=Param(HN_model.i,HN_model.s,initialize=[PI])

 HN_model.u_power=Expression(HN_model.ij, HN_model.s, expr=(HN_model.T/HN_model.ef)*HN_model.Cp_medio*((HN_model.PJ/HN_model.PI for i,j in HN_model.ij))**((HN_model.gama-1)/HN_model.gama)-1*(HN_model.T/HN_model.T0)*(HN_model.P0/HN_model.PPi))

错误:

***AttributeError: 'generator' object has no attribute AttributeError                            Traceback (most recent call last)
<ipython-input-13-65250a010a2a> in <module>()
     15 #HN_model.u_power=Var(HN_model.i,HN_model.j, HN_model.s)
     16 
---> 17 HN_model.u_power=Expression(HN_model.ij, HN_model.s, expr=(HN_model.T/HN_model.ef)*HN_model.Cp_medio*((HN_model.PJ/HN_model.PI for i,j in HN_model.ij))**((HN_model.gama-1)/HN_model.gama)-1*(HN_model.T/HN_model.T0)*(HN_model.P0/HN_model.PPi))
     18 HN_model.u_power=Expression(HN_model.i,HN_model.j, HN_model.s, expr=(HN_model.T/HN_model.ef)*HN_model.Cp_medio*((1))**((HN_model.gama-1)/HN_model.gama)-1*(HN_model.T/HN_model.T0)*(HN_model.P0/HN_model.PPi))
     19 HN_model.u_power1=Expression(HN_model.i,HN_model.k, HN_model.s, expr=(HN_model.T/HN_model.ef)*HN_model.Cp_medio*((1))**((HN_model.gama-1)/HN_model.gama)-1*(HN_model.T/HN_model.T0)*(HN_model.P0/HN_model.PPi))

pyomo/core/expr/numvalue.pyx in pyomo.core.expr.numvalue.NumericValue.__rpow__()

pyomo/core/expr/numeric_expr.pyx in pyomo.core.expr.numeric_expr._generate_other_expression()

AttributeError: 'generator' object has no attribute 'is_expression_type'

【问题讨论】:

  • 你能编辑帖子并显示模型和完整的AttributeError吗?此外,您的模型与your previous question 中的错误相同。参数HN_model.PIIndexedParam 并且您没有使用索引来调用每个值
  • 好的。完毕!我用“HN_model.PI for i,j in HN_model.ij”,不正确?

标签: python string set expression pyomo


【解决方案1】:

帕特里夏。

首先,当您创建集合 (HN_model.i, HN_model.j, HN_model.k, HN_model.s) 时,您将分别根据数组 i, j, k, s 的长度创建一个 python 范围。 现在,正如我之前向您推荐的那样,您可以毫无问题地使用字符串列表:

i=['U4241', 'U241', 'U241A']
HN_model.i=Set(initialize=i)

这将帮助您避免为数据生成新列表和范围。

现在,为你AttributeError是专门由这部分生成的:

(HN_model.PJ/HN_model.PI for i,j in HN_model.ij)

记住,HN_model.PJ 是一个IndexedParam,你可以把它想象成一个传统的python dict。这意味着对于调用每个元素,您需要始终传递一个键,而该键将取决于创建时的参数化。在这种情况下,您使用HN_model.PJ=Param(HN_model.j,HN_model.s,initialize=[PJ]) 创建它。这意味着HN_model.PJ 是一个类似字典的组件,这意味着它取决于js 的值。如果你按照我上面告诉你的那样对集合建模,这意味着HN_model.PJ 得到了以下索引,同样的推理也适用于HN_model.PI 参数:

>>>HN_model.PJ.display()

PJ : Size=6, Index=PJ_index, Domain=Any, Default=None, Mutable=False
Key          : Value
('U1280', 1) :    30
('U2280', 1) :    30
 ('U283', 1) :  88.5
('U283A', 1) :  88.5
('U3283', 1) :    30
('U4283', 1) :   137

当您使用和IndexedParam(或IndexedVar)时,您有两个选项:使用索引调用它,为每个索引生成一个表达式,或者使用索引但在数学函数内部调用它,生成一个表达式与所有索引。比如

每个索引的表达式

...HN_model.PJ[j,s]/HN_model.PI[i,s])**(HN_model.gama-1)...

所有索引的单个表达式

...sum(sum(sum(HN_model.PJ[j,s]/HN_model.PI[i,s] for i in HN_model.i)for j in HN_model.j)for s in HN_model.s)...

错误来自于调用HN_model.PJ 而不使用表达式中的任何索引。

那么,你就可以正确使用你的模型了:

from pyomo.environ import *
HN_model=ConcreteModel()

i=['U4241', 'U241', 'U241A']
HN_model.i=Set(initialize=i)
j=['U4283', 'U283', 'U283A', 'U3283', 'U2280', 'U1280']
HN_model.j=Set(initialize=j)
k=['PSA4241', 'PSA241', 'PSA241A', 'PSA3241']
HN_model.k=Set(initialize=k)
s=[1]
HN_model.s=Set(initialize=s)

HN_model.ij=Set(within=HN_model.i*HN_model.j, initialize = [(i,j) for i in HN_model.i for j in HN_model.j])

HN_model.T=Param(initialize=300.00)
HN_model.Cp_hidrogenio=Param(initialize=29.00)
HN_model.Cp_metano=Param(initialize=50.00)
HN_model.Cp_medio=Param(initialize=35.00)
HN_model.ef=Param(initialize=0.6)
HN_model.T0=Param(initialize=288.7)
HN_model.P0=Param(initialize=1.00)
HN_model.R=Param(initialize=8.314,)
HN_model.PPi=Param(initialize=5.5)
HN_model.gama=Expression(expr=HN_model.Cp_medio/(HN_model.Cp_medio-HN_model.R))

PJ={}
PJ['U4283',1]=137;
PJ['U283',1]=88.5;
PJ['U283A',1]=88.5;
PJ['U3283',1]=30;
PJ['U2280',1]=30;
PJ['U1280',1]=30;
HN_model.PJ=Param(HN_model.j,HN_model.s,initialize=PJ)

PI={}
PI['U4241',1]=21.3;
PI['U241',1]=21.1;
PI['U241A',1]=21.1;
HN_model.PI=Param(HN_model.i,HN_model.s,initialize=PI)

def u_power(model, i,j,s):
    '''This will generate an Expression in Pyomo for each i,j,s index'''
    return (HN_model.T/HN_model.ef)*HN_model.Cp_medio*(HN_model.PJ[j,s]/HN_model.PI[i,s])**((HN_model.gama-1)/HN_model.gama)-1*(HN_model.T/HN_model.T0)*(HN_model.P0/HN_model.PPi)

HN_model.u_power = Expression(HN_model.i, HN_model.j, HN_model.s, rule=u_power, doc=u_power.__doc__)

当你打电话给HN_model.u_power.display() 时,这会给你:

u_power : Size=18
    Key                   : Value
     ('U241', 'U1280', 1) :  19025.64990902805
     ('U241', 'U2280', 1) :  19025.64990902805
      ('U241', 'U283', 1) : 24600.466480257248
     ('U241', 'U283A', 1) : 24600.466480257248
     ('U241', 'U3283', 1) :  19025.64990902805
     ('U241', 'U4283', 1) :  27291.28045776289
    ('U241A', 'U1280', 1) :  19025.64990902805
    ('U241A', 'U2280', 1) :  19025.64990902805
     ('U241A', 'U283', 1) : 24600.466480257248
    ('U241A', 'U283A', 1) : 24600.466480257248
    ('U241A', 'U3283', 1) :  19025.64990902805
    ('U241A', 'U4283', 1) :  27291.28045776289
    ('U4241', 'U1280', 1) : 18983.060990494465
    ('U4241', 'U2280', 1) : 18983.060990494465
     ('U4241', 'U283', 1) : 24545.398458397834
    ('U4241', 'U283A', 1) : 24545.398458397834
    ('U4241', 'U3283', 1) : 18983.060990494465
    ('U4241', 'U4283', 1) :  27230.18910845819

由于HN_model.u_power 依赖于i,j,s 索引,因此无论何时要使用它,都需要使用这些索引HN_model.u_power[i,j,s] 调用它

【讨论】:

  • 非常感谢!
猜你喜欢
  • 2013-03-04
  • 2013-01-14
  • 2017-11-05
  • 2017-06-22
  • 1970-01-01
  • 2020-03-07
  • 1970-01-01
  • 2021-08-17
  • 2023-03-03
相关资源
最近更新 更多