为什么将参数传递给约束函数时,Pyomo行为会发生变化?

时间:2019-01-09 12:12:53

标签: python optimization pyomo

此代码正常工作。

def m(model, i):
    return model.fd_amt[i] <= getattr(model, 'br_sa_ind')[i] * global_m

setattr(model, ind+"_m",Constraint(model.br_standalone_I, rule=m))

但是这个

def m(model, i, ind_name):
    return model.fd_amt[i] <= getattr(model, ind_name)[i] * global_m

setattr(model, ind+"_m",Constraint(rule=m(model,model.model.br_standalone_I, 'br_sa_ind') ))

导致此错误:

  

错误:计算表达式:未初始化的NumericValue没有值   宾语       fd_amt [br_standalone_I]           (表达式:fd_amt [br_standalone_I] <= 13 *           br_sa_ind [br_standalone_I])错误:为约束br_sa_ind_m生成表达式时,规则失败:       ValueError:未初始化的NumericValue对象没有值       fd_amt [br_standalone_I]错误:从数据构造组件'br_sa_ind_m'=没有失败:ValueError:       未初始化的NumericValue对象fd_amt [br_standalone_I]

没有值

Pyomo约束对显式参数有这种行为吗?

2 个答案:

答案 0 :(得分:2)

You can achieve the desired behavior by replacing rule= with expr=:

setattr(model, ind+"_m",Constraint(model.br_standalone_I))
for i in model.br_standalone_I:
    getattr(model, ind+"_m")[i].set_value(expr=m(model, i, 'br_sa_ind'))

The purpose of rule is so that indexed constraint expressions can be constructed using a common rule. If you have a singleton constraint, you can specify the expression using expr.

答案 1 :(得分:1)

您的代码不起作用,因为您使用了函数调用rule=m(...)而不是函数引用rule=m

尽管此解决方案可能无法直接解决您的问题,但可能会带来麻烦。我仍然不知道Pyomo是否允许您询问(将参数传递给规则)。

使用您要传递的参数作为唯一元素创建一个新集合。如果需要,可以在规则函数中适当处理参数的情况下稍后添加更多元素。为简单起见,让我们仅从一个元素开始。

model.S = Set(initialize=['br_sa_ind'])

然后使用此设置作为规则的参数。就像对所有符号都使用a一样,它只有一个元素。 (对于集合S和集合br_standalone_I中的所有元素,应用规则m)。您应该使用

创建约束
Constraint(model.br_standalone_I, model.S, rule=m)

所以您的整个代码看起来像

def m(model, i, ind_name):
    return model.fd_amt[i] <= getattr(model, ind_name)[i] * global_m

setattr(model, ind+"_m",Constraint(model.br_standalone_I, model.S, rule=m))

这并不完全优雅,但应该可以。我还想听听您是否可以在创建约束时为规则指定参数。