I want to add indicator constraints (e.g. if z=0, then x=0
with x>=0
and z
being a binary variable) to my problem written in PuLP
. Obviously, I could make use of the big-M method as suggested here and here.
However, I cannot use the big-M workaround since my term is unbounded within the MILP. I found this post from 2016 stating that PuLP
cannot handle indicator constraints.
Does anyone know if that is still the case or any other solution?
Thanks in advance.
I think, you can try to handle Binary indicator_constraint with GEKKO if2
or if3
methods (if that what you meant)
from gekko import GEKKO
import numpy as np
tm= np.array([0,1,2,3,4,5,6,7,8,9,10,11])
cost= np.array([4, 31, 30, 28, 28, 27, 26, 26, 25, 24, 24, 23 ])
d = np.array([ 0, 8, 9, 9, 10, 10, 10, 11, 12, 14, 16, 18])
cnt= len(tm); print(len(tm))
new_cost = 18
m = GEKKO(remote = False)
# Gekko has an integer tolerance where it can find a solution within 1e-2 of the integer value. This can be adjusted with the solver option minlp_integer_tol
# increase tolerance
m.options.RTOL = 1e-10
m.options.OTOL = 1e-10
m.solver_options = ['minlp_gap_tol 1.0e-5',\
'minlp_maximum_iterations 10000',\
'minlp_max_iter_with_int_sol 10000',\
'minlp_integer_tol 1e-8']
x = m.Array(m.Var,cnt,lb=0,ub=1,integer=True)
# !!!
x1= m.Const(1)
x0= m.Const(0)
m.Maximize(m.sum([ (cost[i]- d[i] - m.if3(cost[i]- d[i] , x1, x0) *new_cost) *x[i] for i in range(cnt) ]))
y = m.Var()
m.Equation(y==m.sum([ (cost[i]- d[i] - m.if3(cost[i]- d[i] , x1, x0) *new_cost) *x[i] for i in range(cnt)] ))
m.options.SOLVER = 1 # APOPT
m.solve()
value = -1* m.options.objfcnval # Maximize need *-1 to get max_val
print("y_total_: ", y.value[0])
# print('Option: ' + str(x))
p.s. or see in GEKKO Special Ordered Set SOS in GEKKO, also described e.g. in lp_solve - milp solver