Pyomo:如何在抽象模型的目标中使用最终数据点?

时间:2016-06-11 00:58:24

标签: python optimization pyomo

我有一个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的最大可能值。

如何创建表达此内容的抽象模型?

1 个答案:

答案 0 :(得分:1)

你正在处理两个有些不同的问题:

TypeError: unhashable type: 'SimpleParam'

由于Pyomo 4.3中的一个错误,您无法直接将简单Param s用作其他组件的索引。也就是说,针对此特定问题的修复程序无法修复您的示例模型。

修复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)

问题在于,在编写Abstract模型时,每个组件只是声明,而不是已定义。因此,Var S被声明存在,但尚未定义(它是一个没有成员的空壳)。这会导致问题,因为Python(而不是Pyomo)会在调用m.S[120]构造函数之前尝试将Objective解析为特定变量。在Abstract模型中使用规则(函数)允许您推迟表达式的解析,直到Pyomo实际构建模型实例。 Pyomo按照您在Abstract模型上声明它们的顺序构造实例组件,因此当它触发obj_rule时,前面的组件(ST和{{1} }}都是构造的,tS的已知点(在这种情况下,边界)有有效成员。