Search code examples
pythonoptimizationpyomo

Definition of binary variable in Pyomo is not working


I'm new to Pyomo (and optimization) and am trying to reproduce a simple approach (see comment from Fengyuan-Shi on https://github.com/Pyomo/pyomo/issues/821) to create a maximum constraint using the Big M method and binary variables. The code returns the correct answer, but the variables u_1 and u_2, which are supposed to be binary (taking values of 0 or 1 only) are actually taking values between 0 and 1. Can anyone see what I'm doing wrong?

import pyomo.environ as pyomo

m = pyomo.ConcreteModel()

m.x = pyomo.Param(initialize=5) 
m.y = pyomo.Param(initialize=9) 
m.z = pyomo.Var(domain = pyomo.NonNegativeReals)
m.u_1 = pyomo.Var(domain = pyomo.Binary)
m.u_2 = pyomo.Var(domain = pyomo.Binary)
m.M = pyomo.Param(initialize=1e3) # Big M

m.o = pyomo.Objective(expr = m.z + 8)
m.cons = pyomo.ConstraintList()


# ensure z is the maximum of x and y, per comment from Fengyuan Shi on https://github.com/Pyomo/pyomo/issues/821
# =============================================================================
m.cons.add(m.x <= m.z) 
m.cons.add(m.y <= m.z) 
m.cons.add(m.x >= m.z - m.M*(1-m.u_1)) 
m.cons.add(m.y >= m.z - m.M*(1-m.u_2))
m.cons.add(m.u_1 + m.u_2 >= 1)  

m.pprint()

solver = pyomo.SolverFactory('ipopt')
status = solver.solve(m)

print("Status = %s" % status.solver.termination_condition)


for v in m.component_objects(pyomo.Var, active=True):
    print ("Variable component object",v, v.value)

When the code is run, the output is: Variable component object z 8.999999912504697 (correct, the maximum of x = 5 and y=9) Variable component object u_1 0.5250908817936364 (expected this to be either 0 or 1) Variable component object u_2 0.5274112114061761 (expected this to be either 0 or 1)


Solution

  • Your construct appears correct. You need to use a different solver.

    ipopt is typically used for non-linear problems and it does not support integer requirements (which includes binary assignment). Specifically, it only supports continuous variables.

    The problem you have is completely linear, so you should be using a linear solver that supports MIP formulations. Your problem is a "Mixed Integer Program" because of the binary requirements. I'd suggest cbc or glpk, both of which are freeware.