I am defining a Pyomo model that should have some mutable Big-M parameters whose values should be dynamically assigned (once). However, I am having a problem with a difference equation as described in this post Error message in difference equation in Pyomo. Here you can see my extremel simplified model in pyomo (that does not make much sense from a logical point of view, but I just want to adress the error):

import pyomo.environ as pyo
import pandas as pd
from pyomo.util.infeasible import log_infeasible_constraints

#Define the model
model = pyo.ConcreteModel()

#Define the sets
model.set_timeslots = pyo.RangeSet(1, 288)

#Define the bigM parameter
model.param_BigM_Surplus_Positive = pyo.Param(model.set_timeslots, mutable=True, default =0)

#Define the variables
model.variable_temperatureBufferStorage = pyo.Var(model.set_timeslots, bounds=(20, 22))
model.variable_surplusPowerTotal = pyo.Var(model.set_timeslots)

#Equations for the Big-M parameters
'''When commenting this Big-M parameter equation out, the model can be solved. Otherwise I get an error for each value of the variable model.variable_temperatureBufferStorage
   variable ERROR: evaluating object as numeric value:
    (object: <class 'pyomo.core.base.var._GeneralVarData'>)
    No value for uninitialized NumericValue object
def BigM_Surplus_PositiveRule (model, t):
    return model.param_BigM_Surplus_Positive [t] == 10

model.constraint_BigM_Surplus_Positive = pyo.Constraint(model.set_timeslots, rule = BigM_Surplus_PositiveRule)

# Defining the constraints 

#Temperature constraint for the buffer storage (space heating) with energetic difference equation
def temperatureBufferStorageConstraintRule(model, t):
    if t == model.set_timeslots.first():
        return model.variable_temperatureBufferStorage[t] == 21
    return model.variable_temperatureBufferStorage[t] == model.variable_temperatureBufferStorage[t-1] 

model.constraint_temperatureBufferStorage = pyo.Constraint (model.set_timeslots, rule=temperatureBufferStorageConstraintRule)

#Equations for the surplus power
def surplusPowerTotalRule (model, t):
    return model.variable_surplusPowerTotal [t] == 1

model.constraint_surplusPowerTotal = pyo.Constraint(model.set_timeslots, rule = surplusPowerTotalRule)


def objectiveRule_combined_general (model):
    return  sum(model.variable_surplusPowerTotal[t] for t in model.set_timeslots)
model.objective_combined_general = pyo.Objective( rule=objectiveRule_combined_general, sense =pyo.minimize)

print("Start of solving")
solver = pyo.SolverFactory('gurobi')
solver.options['MIPGap'] = 1
solver.options['TimeLimit'] = 20
solution = solver.solve(model, tee=True)


The problematic part is when I define the constraints for the mutable Big-M parameter model.param_BigM_Surplus_Positive = pyo.Param(model.set_timeslots, mutable=True, default =0). When they are active and not commented out I get an error from Gurobi telling that the problem is infeasible or unbounded:

Infeasible or unbounded model
WARNING: Loading a SolverResults object with a warning status into
      - termination condition: infeasibleOrUnbounded
      - message from solver: Problem proven to be infeasible or unbounded.

When looking what is causing this problem with from pyomo.util.infeasible import log_infeasible_constraints I can see an error for each value of the variable model.variable_temperatureBufferStorage

ERROR: evaluating object as numeric value:
        (object: <class 'pyomo.core.base.var._GeneralVarData'>)
    No value for uninitialized NumericValue object
ERROR: evaluating object as numeric value:
        (object: <class 'pyomo.core.base.var._GeneralVarData'>)
    No value for uninitialized NumericValue object
ERROR: evaluating object as numeric value:
        (object: <class 'pyomo.core.base.var._GeneralVarData'>)
    No value for uninitialized NumericValue object

Without the Big-M parameter constraints the model is solvable. So my question is why does this error occur when having a mutable parameter and how can I tackle this problem?

  • $\begingroup$ Not sure what you are trying to achieve here but a constraint "0=10" is often considered to be infeasible. $\endgroup$ Apr 16 '21 at 10:03
  • $\begingroup$ Thanks for your comment Erwin. Basically I would like to define a parameter Big-M(t) whose values are assigned to it by using other parameters. I do this in the constraint model.constraint_BigM_Surplus_Positive (for simplicity I just assign the value 10 to it in this simplified example). So the value of the parameter Big-M should be calculated for every timeslot (t). $\endgroup$
    – PeterBe
    Apr 16 '21 at 10:15
  • $\begingroup$ In the defintion of the Big-M parameter model.param_BigM_Surplus_Positive = pyo.Param(model.set_timeslots, mutable=True, default =0) I have to specify a default value otherwise I get a Value Error "ValueError: Error evaluating Param value (param_BigM_Surplus_Positive[1]): The Param value is currently set to an invalid value. This is typically from a scalar Param or mutable Indexed Param without an initial or default value." $\endgroup$
    – PeterBe
    Apr 16 '21 at 10:15
  • $\begingroup$ It is important, even essential, to know the difference between a parameter and a variable. A parameter is constant inside a constraint. The solver can only change variables. $\endgroup$ Apr 16 '21 at 10:20
  • $\begingroup$ Thanks Erwin for your comment. Well, I do understand the difference between a parameter and a variable. The Big-M parameter is in fact a parameter and not a variable. The solver should not change any of its values. The values are all predefined by calculating it for every timeslot (t) using other constant parameters. The calculations are just normal calculations that have nothing to do with a solver. I can tell you that I have exactly the same model implemented in GAMS and there the exactly same Big-M parameter is defined as a parameter $\endgroup$
    – PeterBe
    Apr 16 '21 at 10:28

Based on given model section, model.param_BigM_Surplus_Positive parameter is used in only constraint which is:

model.constraint_BigM_Surplus_Positive = pyo.Constraint(model.set_timeslots, rule = BigM_Surplus_PositiveRule)

You are using BigM_Surplus_PositiveRule for generating constraint which is:

model.param_BigM_Surplus_Positive[t] == 10

But this parameter is defined as 0, therefore model is infeasible. If you want to assign 10 to this parameter, you should use initialize function.

Note: On your model there isn't any big-m constraint. In this question you can find an example.

  • $\begingroup$ Thanks for your answer kur ag. It worked. I really appreciate your help. I upvoted and accepted your answer. $\endgroup$
    – PeterBe
    Apr 20 '21 at 7:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.