Search code examples
pythonoptimizationpyomo

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


This code works correctly.

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

But this

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

results in this error:

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]

Is there a reason Pyomo constraints behave this way with explicit parameters?


Solution

  • 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.