尽管存在可行的解决方案(使用cvxopt python),但是lp的不可行解决方案

时间:2017-09-15 19:29:01

标签: python mathematical-optimization linear-programming cvxopt

我正在尝试找到解决以下问题的lp解决方案,即使我可以手工构建可行点,我似乎从cvxopt获得了不可行的证书。以下是代码示例和代码段

import numpy as np
from cvxopt import solvers, matrix
A = np.array([[0.221, -11.76, -1], [0.2017, -9.88, -1], [0.176, -8.045, 
-1], [0.253, 1.72, 0.]])
print(A)
[[  0.221  -11.76    -1.    ]
[  0.2017  -9.88    -1.    ]
[  0.176   -8.045   -1.    ]
[  0.253    1.72     0.    ]]
b = np.array([-147459573, -139576175, -131383060, 20e6])
x0 = np.array([0.,0.,-np.min(b)])
x1 = np.array([20.e6,8.0e6,71e6])
y0 = np.dot(A,x0)
print(y0<=b)
[ True  True  True  True]
y1 = np.dot(A,x1)
print(y1 <= b)
[ True  True  True  True]
c = np.array([0.,0.,1.])
A = matrix(A)
b = matrix(b)
c = matrix(c)
res = solvers.lp(c,A,b)
pcost       dcost       gap    pres   dres   k/t
0:  1.0031e+08  1.4805e+09  4e+06  2e-03  1e+02  1e+00
Certificate of primal infeasibility found.

从上面可以看出x0,x1显然属于可行集,但解决方案似乎说原始是不可行的。我看错了吗?

1 个答案:

答案 0 :(得分:1)

问题

你的问题缩放非常严重,因为系数非常大且非常小。由于所有这些求解器都使用有限精度的浮点数,因此会引入数值不稳定性

通常的方法是缩放问题或重新制定问题。有大量的书籍和可能的论文(主要是关于预处理的一些章节),但我只是引用Mosek's docs,因为这很容易获得:

  

包含大系数和/或小系数的数据(例如1.0e + 9或1.0e-7)的问题通常难以解决。在具有有限精度的计算中可能会截断有效数字,这可能导致优化器依赖于不准确的计算。由于计算机的工作精度有限,因此应避免使用极端系数。一般而言,优选围绕相同“数量级”的数据,并且我们将提到满足该松散属性的问题,因为其规模良好。如果问题没有得到很好的扩展,MOSEK将尝试通过合适的常量来扩展(乘)约束和变量。 MOSEK解决了缩放问题以改善数值特性。

     

缩放过程是透明的,即报告原始问题的解决方案。重要的是要注意,当在缩放问题上满足终止标准时优化器终止,因此在针对严重缩放的问题进行非缩放之后可能发生显着的原始或双重不可行性。解决这个问题的最佳方法是重新制定它,使其更好地扩展。

     

默认情况下,MOSEK启发式地选择合适的缩放比例。可以使用参数MSK_IPAR_INTPNT_SCALING和MSK_IPAR_SIM_SCALING分别控制内点和单纯形优化器的缩放。

无痛替代方案(至少对于这个问题)

尽管ecos(圆锥解算器;开源)已准备好解决更复杂的问题,但它似乎在这里做了更好的预处理并且可以解决您的问题。调用ecos的建模框架是cvxpy

import numpy as np

A = np.array([[0.221, -11.76, -1],
              [0.2017, -9.88, -1],
              [0.176, -8.045, -1],
              [0.253, 1.72, 0.]])

b = np.array([-147459573, -139576175, -131383060, 20e6])
c = np.array([0, 0, 1])

""" TRY CVXPY + ECOS """

from cvxpy import *
x = Variable(3)
constraints = [A*x <= b, x >= 0]
objective = Minimize(c * x)
problem = Problem(objective, constraints)
problem.solve(verbose=True)
print('problem state: ', problem.status)
print('solution: ')
x_sol = np.array(x.value.flat)
print(x_sol)
print( (A.dot(x_sol) <= b) )

输出:

ECOS 2.0.4 - (C) embotech GmbH, Zurich Switzerland, 2012-15. Web: www.embotech.com/ECOS

It     pcost       dcost      gap   pres   dres    k/t    mu     step   sigma     IR    |   BT
 0  +7.905e+06  +1.394e+08  +1e+08  2e-01  9e-01  1e+00  2e+07    ---    ---    1  1  - |  -  -
 1  +1.415e+07  +5.847e+07  +3e+07  7e-02  3e-01  6e+05  4e+06  0.7593  3e-02   0  0  0 |  0  0
 2  +3.447e+07  +5.278e+07  +1e+07  3e-02  2e-01  1e+06  2e+06  0.8506  2e-01   0  0  0 |  0  0
 3  +4.015e+07  +4.038e+07  +1e+06  4e-04  9e-02  2e+04  2e+05  0.9890  1e-03   0  0  0 |  0  0
 4  +3.820e+07  +3.820e+07  +1e+05  5e-06  4e-02  3e+02  2e+04  0.9856  1e-04   0  0  0 |  0  0
 5  +3.784e+07  +3.784e+07  +3e+03  6e-08  8e-03  7e+01  4e+02  0.9890  2e-03   0  0  0 |  0  0
 6  +3.784e+07  +3.784e+07  +4e+01  7e-10  2e-04  9e-01  5e+00  0.9890  1e-04   0  0  0 |  0  0
 7  +3.784e+07  +3.784e+07  +4e-01  8e-12  5e-06  1e-02  5e-02  0.9890  1e-04   0  0  0 |  0  0
 8  +3.784e+07  +3.784e+07  +4e-03  9e-14  7e-08  1e-04  6e-04  0.9890  1e-04   0  0  0 |  0  0
 9  +3.784e+07  +3.784e+07  +5e-05  1e-15  1e-09  2e-06  6e-06  0.9890  1e-04   1  0  0 |  0  0

OPTIMAL (within feastol=1.0e-09, reltol=1.3e-12, abstol=5.0e-05).
Runtime: 0.003211 seconds.

problem state:  optimal
solution:
[  5.49533698e-05   1.16279070e+07   3.78365484e+07]
[ True  True  True  True]

Mosek也应该能够解决这个问题!