python - CPLEX 目标函数中的线性项和二次项

标签 python linear-programming cplex quadratic-programming

我想最小化一个相当简单的目标函数,但我在从 Python API 到 CPLEX 进行正确调用时遇到了问题

我了解了如何使用 set_quadraticset_quadratic_coefficients here但这并没有解决我的问题。

我的目标函数有一组线性变量和一组二次变量

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) )]
    )

一切正常,直到最后一次调用添加二次项。此时,CPLEX 会抛出以下错误 CPLEX Error 1226: Array Entry 13919 not ascending. 两次,忽略该命令,Python 代码继续。

我查了一下error ,但这似乎也对我没有帮助。

我确实尝试重写上面的内容,首先按名称和下限添加变量...然后调用 set_linearset_quadratic,但这并没有'也没有帮助。

我在这里缺少什么?

最佳答案

如果您使用可分离的二次目标函数调用 set_quadratic,则它对应于 CPXXcopyqpsep 。如果您使用不可分离的二次目标函数调用 set_quadratic,则它对应于 CPXXcopyquad 。我同意您遇到的错误并不是特别有用,但是如果您知道它来自 Callable C Library 中的位置,那么它会更有意义。

话虽如此,这是一个完整的示例,使用您的代码片段和一些虚拟输入:

import cplex

class MockTarget(object):
    pass

# Dummy data for testing

numB = 3
numQ = 3
deltas = [0.1, 0.1, 0.1]
problem = cplex.Cplex()

target = MockTarget()
target.v = [1, 2, 3]

# Build the problem

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)

# Print without quadratic terms so you can see the progression.
problem.write('test1.lp')

# Separable Q

qsepvec = []
for tpl in varNames:
    if tpl in sContent:
        qsepvec.append(1.0)
    else:
        qsepvec.append(0.0)
print qsepvec

problem.objective.set_quadratic(qsepvec)

problem.write('test2.lp')

# Inseparable Q (overwrites previous Q)

qmat = []
for tpl in varNames:
    if tpl in sContent:
        sp = cplex.SparsePair(ind=[tpl[0]], val=[1.0])
        qmat.append(sp)
    else:
        sp = cplex.SparsePair(ind=[], val=[])
        qmat.append(sp)
print qmat

problem.objective.set_quadratic(qmat)

problem.write('test3.lp')

我已经以长篇形式写下了它,而不是使用列表理解来使其更加清晰。 LP文件的内容如下:

测试1.lp:

\ENCODING=ISO-8859-1
\Problem name: 

Minimize
 obj: b0 + b1 + b2 + q0 + q1 + q2 + 10 delta0 + 10 delta1 + 10 delta2 + 0 s0
      + 0 s1 + 0 s2 - mu
Bounds
      delta0 >= 1
      delta1 >= 1
      delta2 >= 1
End

test2.lp

\ENCODING=ISO-8859-1
\Problem name: 

Minimize
 obj: b0 + b1 + b2 + q0 + q1 + q2 + 10 delta0 + 10 delta1 + 10 delta2 + 0 s0
      + 0 s1 + 0 s2 - mu + [ s0 ^2 + s1 ^2 + s2 ^2 ] / 2
Bounds
      delta0 >= 1
      delta1 >= 1
      delta2 >= 1
End

test3.lp

\ENCODING=ISO-8859-1
\Problem name: 

Minimize
 obj: b0 + b1 + b2 + q0 + q1 + q2 + 10 delta0 + 10 delta1 + 10 delta2 + 0 s0
      + 0 s1 + 0 s2 - mu + [ s0 ^2 + s1 ^2 + s2 ^2 ] / 2
Bounds
      delta0 >= 1
      delta1 >= 1
      delta2 >= 1
End

您可以看到 test2.lp 和 test3.lp 是相同的(后者覆盖了前者,但做了相同的事情)。希望这能让它更容易理解一些。一般来说,使用这种打印 LP 的技术来解决非常简单的问题,是更有用的调试技术之一。

您还应该查看 CPLEX 附带的 python 示例。例如,qpex1.py、miqpex1.py、indefqpex1.py。

关于python - CPLEX 目标函数中的线性项和二次项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38949055/

相关文章:

指定范围内的Python bin数据

python - 在 CyLP 中初始化整数变量

optimization - 使用 CPLEX 检查新变量降低的成本

python - 安装 CPLEX 12.6 for Python 时出错

python - TensorFlow - 值错误 : features should be a dictionary of `Tensor` s

python - 提取从 CSV 排序的两列

optimization - Gurobi优化结果写入Csv文件

mathematical-optimization - 最佳开源混合整数优化求解器

c++ - 变量的复杂约束函数

python - 如何在 MacOS 上使用 QGLFormat 更改 OpenGL 版本?