I'm trying to convert some code from pure CPLEX to CVXPY with the CPLEX solver. The original code goes like this:
p = cplex.Cplex()
p.objective.set_sense(p.objective.sense.maximize)
obj = np.zeros(numCols)
for i in range(numSamples):
if labels[i] == 0:
for b in range(numBuckets):
obj[zv_ + b*numSamples + i] = C
else:
for b in range(numBuckets):
obj[zv_ + numBuckets*numSamples + b*numSamples + i] = 1
p.linear_constraints.add(rhs=rhs,senses=senses)
p.linear_constraints.set_names(zip(range(constraint_cnt),cnames))
lb = np.zeros(numCols)
ub = np.ones(numCols)
p.variables.add(obj = obj, lb = lb, ub = ub, columns=cols, types=types, names=names)
p.parameters.timelimit.set(maxtime)
p.solve()
sol = p.solution
This is my attempt at converting it to CVXPY syntax:
import cvxpy as cp
obj = np.zeros(numCols)
for i in range(numSamples):
if labels[i] == 0:
for b in range(numBuckets):
obj[zv_ + b*numSamples + i] = C
else:
for b in range(numBuckets):
obj[zv_ + numBuckets*numSamples + b*numSamples + i] = 1
objective = cp.Maximize(sum(obj))
What I'm very confused by is the way CPLEX specifies 'rhs', as well as 'senses'. What are these supposed to be?
The CPLEX Python API documentation for Cplex.linear_constraints.add says:
senses must be either a list of single-character strings or a string containing the senses of the linear constraints. Each entry must be one of 'G', 'L', 'E', and 'R', indicating greater-than, less-than, equality, and ranged constraints, respectively.
rhs is a list of floats, specifying the righthand side of each linear constraint.
CVXPY is a modeling language, so rather than specifying the sense as 'G', 'L', 'E', you would use >=
, <=
, and ==
(i.e., Python comparison operators). The righthand side of the constraints, will be a number for an individual constraint (e.g., a Python float
or int
), or perhaps a numpy array for a group of constraints.
The CVXPY examples should give you a good idea of how do things.