# Semi continuous constraints in CPLEX Python

I have a semi-continuous optimization problem reformulated as a MIQP optimization problem.

My objective has a quadratic form $$x^{T}Qx$$ and my $$x_{i}$$ are such as $$x_{i} \in [m,M] \cup \{0\}$$. Therefore, I introduce a vector of binary variables $$y$$ such as $$y_{i} \in \{0,1\}$$ and consider the following constraint on the $$x_{i}$$ : $$m * y_{i} \leq x_{i} \leq M * y_{i}$$.

My optimization problem is hence defined by the objective function, the ranged constraint on the $$x_{i}$$ and the binary constraint on $$y_{i}$$.

I'm trying to solve my problem with CPLEX but I'm having trouble specifying the ranged constraint on the $$x_{i}$$. Here's what I have so far for the constraints :

myProblem=cplex.Cplex()

#define the variables
names_amounts=["amounts " + str(i) for i in range(50))]
names_binary=["binary " + str(i) for i in range(50))]
lb=*50,
names=names_amounts)
lb=*50,
names=names_binary)
for i in range(50):
myProblem.variables.set_types("amounts " + str(i), myProblem.variables.type.continuous)
myProblem.variables.set_types("binary " + str(i), myProblem.variables.type.integer)

#define the constraints
lin_expr=[[names_amounts,*50]],
senses=['E'],
rhs=[1.0])


I need to add the ranged constraint but can't figure out how. I know my senses attribute will become ['E'] + ['R' for i in range(50)] but what about the lin_expr and rhs attributes ? How to specify the dependance of the rhs attribute with the binary variables ?

• I am not a CPLEX user, but I suspect that a range constraint requires constant lower and upper bounds and that here you should instead declare two separate inequality constraints. – RobPratt Sep 2 at 14:56
• Yes sorry maybe my question was unclear. CPLEX has the particularity to only consider constraints one by one, and therefore I can't just put an inequality between two vectors (especially since the bound vectors depend on the binary variables of the problem). At least it's the feeling I have. If anyone could confirm or not what I say and show me how to do it I'd be very grateful. – FredNgu Sep 2 at 15:06

that s quite easy to do with docplex python API:

let me change

https://github.com/AlexFleischerParis/zoodocplex/blob/master/zoosemiinteger.py

from

into semicontinuous

from docplex.mp.model import Model

# original model

mdl = Model(name='buses')
nbbus40 = mdl.semicontinuous_var(4,20,name='nbBus40')
nbbus30 = mdl.semicontinuous_var(4,20,name='nbBus30')
mdl.add_constraint(nbbus40*40 + nbbus30*30 >= 300, 'kids')
mdl.minimize(nbbus40*500 + nbbus30*400)

mdl.solve()

for v in mdl.iter_semicontinuous_vars():
print(v," = ",v.solution_value

• EDIT : it works great thank you ! I don't know why I didn't hear of docplex before, it's way easier to use than other solvers. What are the advantages of cplex compared to docplex then ? – FredNgu Sep 2 at 15:45
• Well to me OPL is even easier than docplex python API linkedin.com/pulse/… but for sure docplex is much easier to use than the cplex python matrix API. The cplex matrix pytho API has some features that are not yet in docplex like sensitivity analysis but then you can call the matrix api from docplex lise shown at stackoverflow.com/questions/62475139/… – Alex Fleischer Sep 2 at 16:08