I would like to minimize an objective function which is rather simple, but I am somehow having problems making the correct calls to from the Python API to CPLEX
I looked at how to use set_quadratic
and set_quadratic_coefficients
here but that didn't result in a solution to my problem.
My objective function has a set of linear variables and a set of quadratic variables
varCoefs = [1]*(numB + numQ)
varLower = [0]*(numB + numQ)
varNames = [(x,"b%s"%x) for x in range( numB )]
varNames += [(len(varNames) + x,"q%s"%x) for x in range( numQ )]
varCoefs += [10]*len(deltas)
varLower += [1]*len(deltas)
varNames += [(len(varNames) + x,"delta%s"%x) for x in range( len(deltas) )]
varCoefs += [0]*len(target.v)
varLower += [0]*len(target.v)
sContent = [(len(varNames) + x,"s%s"%x) for x in range( len(target.v) )]
varNames += sContent
varCoefs += [-1]
varLower += [0]
varNames += [(len(varNames),'mu')]
problem.variables.add(obj = varCoefs, lb = varLower)
problem.variables.set_names(varNames)
# problem.objective.set_quadratic_coefficients([[['s%s' % x], [1]] for x in range( len(target.v) )])
problem.objective.set_quadratic(
[cplex.SparsePair(ind=[sContent[x][0]], val=[1]) for x in range( len(target.v) )]
)
Everything works up to the last call add the quadratic terms. At which point CPLEX throws the following error CPLEX Error 1226: Array entry 13919 not ascending.
twice, ignoring the command, and the Python code continues.
I looked up the error, but that didn't seem to help me either.
I did try re-writing the above to add the variables by name and lower bound first... and then call set_linear
and set_quadratic
afterward, but that doesn't help either.
What am I missing here?
I solved the problem by adding the quadratic terms first, setting their coefficients, and then adding the linear terms in a separate call see below.
problem.objective.set_sense(problem.objective.sense.minimize)
varLower = [0]*len(target.v)
varNames = ["s%s"%x for x in range( len(target.v) )]
problem.variables.add(names=varNames, lb=varLower)
problem.objective.set_quadratic(
[[[x],[1]] for x in range( len(target.v) )]
)
varCoefs = [-1]
varLower = [0]
varNames = ['mu']
varCoefs += [1]*(numB + numQ)
varLower += [0]*(numB + numQ)
varNames += ["b%s"%x for x in range( numB )]
varNames += ["q%s"%x for x in range( numQ )]
varCoefs += [10]*len(deltas)
varLower += [1]*len(deltas)
varNames += ["delta%s"%x for x in range( len(deltas) )]
problem.variables.add(names=varNames, lb=varLower, obj=varCoefs)
However, I would still like to know why it works this way, and not the other way.