0

我有一个 Pyomo 模型,其形式为:

from pyomo.environ import *
from pyomo.dae import *

m      = AbstractModel()
m.t    = ContinuousSet(bounds=(0,120)) 
m.T    = Param(default=120)
m.S    = Var(m.t, bounds=(0,None))
m.Sdot = DerivativeVar(m.S)
m.obj  = Objective(expr=m.S[120],sense=maximize)

请注意,目标m.obj依赖于参数m.T。尝试运行它会给出错误:

TypeError: unhashable type: 'SimpleParam'

使用一个值,例如expr=m.S[120]给出错误:

ValueError: Error retrieving component S[120]: The component has not been constructed.

在这两种情况下,我的目标是相同的:优化S在地平线上的最大可能值。

如何创建表达这一点的抽象模型?

4

1 回答 1

1

您遇到了两个不同的问题:

TypeError: unhashable type: 'SimpleParam'

由于 Pyomo 4.3 中的一个错误,您不能直接使用 simple Params 作为其他组件的索引。也就是说,此特定问题的修复不会修复您的示例模型。

修复声明的技巧是将表达式Objective封装在规则中:Objective

def obj_rule(m):
    return m.S[120]
    # or better yet:
    #   return m.S[m.T]
    # or 
    #   return m.S[m.t.last()]
m.obj  = Objective(rule=obj_rule,sense=maximize)

问题在于,当您编写抽象模型时,每个组件都只是被声明,而不是被定义。因此,声明 VarS存在,但尚未定义(它是一个没有成员的空壳)。这会导致一个问题,因为 Python(不是 Pyomo)会在调用构造函数之前立即尝试将 解析m.S[120]为特定变量。Objective在抽象模型中使用规则(函数)允许您推迟表达式的解析,直到 Pyomo 实际构建模型实例。Pyomo 以与您在 Abstract 模型上声明它们的顺序相同的顺序构造实例组件,因此当它触发 时obj_rule,先前的组件(STt) 都是构造的,并且在(在本例中为边界)S的已知点处具有有效成员。ContinuousSet

于 2016-08-23T22:37:09.213 回答