为什么在将参数传递给约束函数时 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
.
指定表达式
这段代码工作正常。
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
.