CPLEX 二次 objective CPLEX 错误 1017:不可用于混合整数问题
CPLEX quadratic objective CPLEX Error 1017: Not available for mixed-integer problems
我正在尝试使用 cplex 求解以下线性程序:
def generate_linear_program(self):
problem = cplex.Cplex()
problem.objective.set_sense(problem.objective.sense.minimize)
for index, track in enumerate(self.tracks):
tokens = track['track'].split('_')
problem.variables.add(names = ['c' + str(tokens[1])], ub = [1.0], types = ['C'])
problem.variables.add(names = ['e' + str(index) for index, param in enumerate(self.params)],
types = ['C'] * len(self.params),
ub = [param['c'] - param['u'] * param['r'] for param in self.params],
lb = [param['c'] - param['u'] * param['r'] - param['c'] * sum(param['tracks'][track] for track in param['tracks']) for param in self.params])
problem.variables.add(names = ['l' + str(index) for index, param in enumerate(self.params)],
#obj = [1.0] * len(self.params),
types = ['C'] * len(self.params))
problem.objective.set_quadratic([0.0] * len(self.tracks) + [1.0] * len(self.params) + [0.0] * len(self.params))
# add some linear constraints here
problem.solve()
当我调用 solve()
时,Cplex 抱怨错误消息 CPLEX Error 1017: Not available for mixed-integer problems
。如果我删除上面的二次 objective 并通过取消注释上面的注释代码行 (obj = [1.0] * len(self.params),
) 来添加线性 objective,它可以正常工作。
堆栈跟踪:
File "/share/src/python/kmer/programming.py", line 373, in solve
problem.solve()
File "/home/user/local/cplex/lib/python/cplex/__init__.py", line 998, in solve
_proc.qpopt(self._env._e, self._lp)
File "/home/user/local/cplex/lib/python/cplex/_internal/_procedural.py", line 499, in qpopt
check_status(env, status)
File "/home/user/local/cplex/lib/python/cplex/_internal/_procedural.py", line 171, in __call__
raise CplexSolverError(error_string, env, status)
cplex.exceptions.errors.CplexSolverError: CPLEX Error 1017: Not available for mixed-integer problems.
为了更好地了解这里发生的事情,当 objective 是二次方程时,我试图最小化一些误差项的平方和。当 objective 变为线性时,我正在最小化这些项的绝对值之和。名称以 e
开头的变量是误差项,l
将通过这些约束成为它们的绝对值:
for index, params in enumerate(self.params):
problem.linear_constraints.add(
lin_expr = [cplex.SparsePair(
ind = [len(self.tracks) + len(self.params) + index, len(self.tracks) + index],
val = [1.0, 1.0],
)],
rhs = [0],
senses = ['G']
)
problem.linear_constraints.add(
lin_expr = [cplex.SparsePair(
ind = [len(self.tracks) + len(self.params) + index, len(self.tracks) + index],
val = [1.0, -1.0],
)],
rhs = [0],
senses = ['G']
)
l<index>
变量在二次方程 objective 的存在下实际上是无用的。
还有其他线性约束我不能在这里包括但它们绝对不是问题的原因,因为以下两个原因:
- 线性 objective 在他们面前没有问题
- 当我使用二次 objective.
将它们注释掉时,我仍然遇到同样的错误
我在这里错过了什么?
Cplex.variables.add 的文档中很容易忽略以下注释:
If types is specified, the problem type will be a MIP, even if all
variables are specified to be continuous.
如果您从对 Cplex.variables.add
的调用中删除可选的 types
参数,问题应该就会消失。例如,而不是:
problem.variables.add(names = ['c' + str(tokens[1])], ub = [1.0], types = ['C'])
使用:
problem.variables.add(names = ['c' + str(tokens[1])], ub = [1.0])
当你有一个线性 objective 时它起作用的原因是它被传递到 CPXmipopt
,作为一个方便,在 CPXlpopt
失败后 CPXERR_NOT_FOR_MIP
(错误 1017)。然而,当我们调用 CPXqpopt
时,此逻辑不适用。
我正在尝试使用 cplex 求解以下线性程序:
def generate_linear_program(self):
problem = cplex.Cplex()
problem.objective.set_sense(problem.objective.sense.minimize)
for index, track in enumerate(self.tracks):
tokens = track['track'].split('_')
problem.variables.add(names = ['c' + str(tokens[1])], ub = [1.0], types = ['C'])
problem.variables.add(names = ['e' + str(index) for index, param in enumerate(self.params)],
types = ['C'] * len(self.params),
ub = [param['c'] - param['u'] * param['r'] for param in self.params],
lb = [param['c'] - param['u'] * param['r'] - param['c'] * sum(param['tracks'][track] for track in param['tracks']) for param in self.params])
problem.variables.add(names = ['l' + str(index) for index, param in enumerate(self.params)],
#obj = [1.0] * len(self.params),
types = ['C'] * len(self.params))
problem.objective.set_quadratic([0.0] * len(self.tracks) + [1.0] * len(self.params) + [0.0] * len(self.params))
# add some linear constraints here
problem.solve()
当我调用 solve()
时,Cplex 抱怨错误消息 CPLEX Error 1017: Not available for mixed-integer problems
。如果我删除上面的二次 objective 并通过取消注释上面的注释代码行 (obj = [1.0] * len(self.params),
) 来添加线性 objective,它可以正常工作。
堆栈跟踪:
File "/share/src/python/kmer/programming.py", line 373, in solve
problem.solve()
File "/home/user/local/cplex/lib/python/cplex/__init__.py", line 998, in solve
_proc.qpopt(self._env._e, self._lp)
File "/home/user/local/cplex/lib/python/cplex/_internal/_procedural.py", line 499, in qpopt
check_status(env, status)
File "/home/user/local/cplex/lib/python/cplex/_internal/_procedural.py", line 171, in __call__
raise CplexSolverError(error_string, env, status)
cplex.exceptions.errors.CplexSolverError: CPLEX Error 1017: Not available for mixed-integer problems.
为了更好地了解这里发生的事情,当 objective 是二次方程时,我试图最小化一些误差项的平方和。当 objective 变为线性时,我正在最小化这些项的绝对值之和。名称以 e
开头的变量是误差项,l
将通过这些约束成为它们的绝对值:
for index, params in enumerate(self.params):
problem.linear_constraints.add(
lin_expr = [cplex.SparsePair(
ind = [len(self.tracks) + len(self.params) + index, len(self.tracks) + index],
val = [1.0, 1.0],
)],
rhs = [0],
senses = ['G']
)
problem.linear_constraints.add(
lin_expr = [cplex.SparsePair(
ind = [len(self.tracks) + len(self.params) + index, len(self.tracks) + index],
val = [1.0, -1.0],
)],
rhs = [0],
senses = ['G']
)
l<index>
变量在二次方程 objective 的存在下实际上是无用的。
还有其他线性约束我不能在这里包括但它们绝对不是问题的原因,因为以下两个原因:
- 线性 objective 在他们面前没有问题
- 当我使用二次 objective. 将它们注释掉时,我仍然遇到同样的错误
我在这里错过了什么?
Cplex.variables.add 的文档中很容易忽略以下注释:
If types is specified, the problem type will be a MIP, even if all variables are specified to be continuous.
如果您从对 Cplex.variables.add
的调用中删除可选的 types
参数,问题应该就会消失。例如,而不是:
problem.variables.add(names = ['c' + str(tokens[1])], ub = [1.0], types = ['C'])
使用:
problem.variables.add(names = ['c' + str(tokens[1])], ub = [1.0])
当你有一个线性 objective 时它起作用的原因是它被传递到 CPXmipopt
,作为一个方便,在 CPXlpopt
失败后 CPXERR_NOT_FOR_MIP
(错误 1017)。然而,当我们调用 CPXqpopt
时,此逻辑不适用。