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

Why Does Pyomo Behavior Change When Passing parameters to constraint function?

这段代码工作正常。

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') ))

导致此错误:

ERROR: evaluating expression: No value for uninitialized NumericValue object fd_amt[br_standalone_I] (expression: fd_amt[br_standalone_I] <= 13 * br_sa_ind[br_standalone_I]) ERROR: Rule failed when generating expression for constraint br_sa_ind_m: ValueError: No value for uninitialized NumericValue object fd_amt[br_standalone_I] ERROR: Constructing component 'br_sa_ind_m' from data=None failed: ValueError: No value for uninitialized NumericValue object fd_amt[br_standalone_I]

Pyomo 约束以这种方式使用显式参数是否有原因?

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

虽然此解决方案可能无法直接回答您的问题,但它可能会提供一个解决方法。我仍然不知道 Pyomo 是否允许您的要求(将参数传递给规则)。

使用您要作为唯一元素传递的参数创建一个新集。如果您在规则的函数中充分处理了参数,则以后可以根据需要添加更多元素。为简单起见,让我们从一个元素开始。

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

然后使用这个集合作为您的规则的参数。这就像使用一个 for all 表示法,只有一个元素。 (对于集合 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))

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

您可以通过将 rule= 替换为 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'))

rule 的目的是使索引约束表达式可以使用通用规则构造。如果您有单例约束,则可以使用 expr.

指定表达式