【问题标题】:scipy.optimize.linprog seems to solve the task but doesn't return the x?scipy.optimize.linprog 似乎解决了任务但不返回 x?
【发布时间】:2017-01-21 07:32:50
【问题描述】:

我正在尝试使用 scipy.optimize.linprog 解决一个非常简单的线性程序,并且该函数似乎做了我想要它做的事情,但不知何故它没有返回“x”(它确实返回了正确的最小函数值)

仅举一个简单的例子(在 matlab 表示法中),我有一个 2-D a=[a1; a2] 和简单的线性约束 [1, 2] * a = 1,并且想要最小化 a 的 L1 范数。最佳值应该是 a=[0, 0.5]。

据我所知,我可以通过使用一个额外的变量 s 以标准形式对此进行表述,例如 b>=abs(a)(即 ab

所以我定义 x= [a; b],将其插入 scipy 的 linprog,它返回成功,我得到正确答案:sum(b) 的最佳值为 0.5。但是,它返回的 x 充满了 nan 而不是 [0; 0.5; 0; 0.5]

代码如下:

A = np.array([1,2]).reshape([1,2])
b_eq = np.array([1])
ones = np.ones([2,])
zeros = np.zeros([2,])
zerosm = np.zeros([1, 2])
eye = np.eye(2)
c = np.hstack([zeros, ones])
A_ub = np.vstack([np.hstack([eye, -eye]), np.hstack([-eye, -eye])])
b_ub = np.hstack([zeros, zeros])
A_eq = np.hstack([A, zerosm])
res = scipy.optimize.linprog(c, A_ub=A_ub, b_ub=b_ub, bounds=(None, None),
                             A_eq=A_eq, b_eq=b_eq)

结果:

success: True
 status: 0
    fun: 0.5
      x: array([ nan,  nan,  nan,  nan])
    nit: 3
  slack: array([ 0.,  0.,  0.,  1.])
message: 'Optimization terminated successfully.'

即x 是nan而不是解决方案。函数值是正确的(0.5),并且松弛似乎很好 - 根据 scipy docs 松弛 0 表示约束处于活动状态,因此第一个和第三个零表示 a1=b1=0,第二个零表示 a2=b2并且它们不为零(否则第 4 个 slack 也将为 0)。这也是预期的,因为 [0, 0.5] 是解决方案。

我做错了什么?这是一个错误吗? (使用 scipy 0.15.1)

谢谢!

【问题讨论】:

  • @warren-weckesser 对不起,我在简化问题时复制粘贴错误,它应该是 A,现在编辑
  • 谢谢。当我使用 scipy 0.18.0 运行您的代码时,我得到x: array([ 0. , 0.5, 0. , 0.5])nit: 4。结果的其他属性和你的一样。
  • 我明白了,看来我在一个老错误上浪费了我的时间。谢谢!
  • 我如何在这里给你信用?如果你发布它,我会接受你的回答
  • 我会让我的评论成为答案。

标签: scipy linear-programming


【解决方案1】:

显然您遇到了自 0.15.1 版以来已修复的错误。

当我使用 scipy 0.18.0 运行您的代码时,我得到:

In [3]: import scipy.optimize

In [4]: %paste
A = np.array([1,2]).reshape([1,2])
b_eq = np.array([1])
ones = np.ones([2,])
zeros = np.zeros([2,])
zerosm = np.zeros([1, 2])
eye = np.eye(2)
c = np.hstack([zeros, ones])
A_ub = np.vstack([np.hstack([eye, -eye]), np.hstack([-eye, -eye])])
b_ub = np.hstack([zeros, zeros])
A_eq = np.hstack([A, zerosm])
res = scipy.optimize.linprog(c, A_ub=A_ub, b_ub=b_ub, bounds=(None, None),
                             A_eq=A_eq, b_eq=b_eq)

## -- End pasted text --

In [5]: res
Out[5]: 
     fun: 0.5
 message: 'Optimization terminated successfully.'
     nit: 4
   slack: array([ 0.,  0.,  0.,  1.])
  status: 0
 success: True
       x: array([ 0. ,  0.5,  0. ,  0.5])

【讨论】:

    【解决方案2】:

    我尝试使用scipy 1.3.1 解决您的问题,并且效果很好:

    con: array([  7.07545134e-12])
         fun: 0.49999999999882094
     message: 'Optimization terminated successfully.'
         nit: 4
       slack: array([  1.07107656e-11,  -4.48552306e-12,  -4.75552930e-12,
             1.00000000e+00])
      status: 0
     success: True
           x: array([ -7.73314746e-12,   5.00000000e-01,   2.97761815e-12,
             5.00000000e-01])
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多