scipy.optimize.linprog 似乎解决了任务,但 return x 不是吗?
scipy.optimize.linprog seems to solve the task but doesn't return the x?
我正在尝试使用 scipy.optimize.linprog 求解一个非常简单的线性程序,看起来该函数可以执行我希望它执行的操作,但不知何故它没有 return 'x'(它 return 正确的最小函数值)
仅举一个简单的例子(用 matlab 表示法),我有一个二维 a=[a1; a2] 和简单的线性约束 [1, 2] * a = 1,并希望最小化 a 的 L1 范数。最优应该是 a=[0, 0.5].
据我所知,我可以通过使用一个额外的变量 s 以标准形式制定这个,例如 b>=abs(a)(即 a-b<=0 和 -a-b<=0)并最小化总和(b) 受制于这些约束和原来的等式约束 [1, 2] * a = 1.
所以我定义x=[a; b],插入scipy的linprog,return成功,得到正确答案:sum(b)的最优值为0.5。但是,它 returns 的 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 文档,松弛度为 0 表示约束处于活动状态,因此第一个和第三个零表示 a1=b1=0,第二个零表示 a2=b2 并且它们不为零(否则第 4 个松弛也将为 0)。这再次符合预期,因为 [0, 0.5] 是解决方案。
我做错了什么?这是一个错误吗? (使用 scipy 0.15.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])
我尝试用 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])
我正在尝试使用 scipy.optimize.linprog 求解一个非常简单的线性程序,看起来该函数可以执行我希望它执行的操作,但不知何故它没有 return 'x'(它 return 正确的最小函数值)
仅举一个简单的例子(用 matlab 表示法),我有一个二维 a=[a1; a2] 和简单的线性约束 [1, 2] * a = 1,并希望最小化 a 的 L1 范数。最优应该是 a=[0, 0.5].
据我所知,我可以通过使用一个额外的变量 s 以标准形式制定这个,例如 b>=abs(a)(即 a-b<=0 和 -a-b<=0)并最小化总和(b) 受制于这些约束和原来的等式约束 [1, 2] * a = 1.
所以我定义x=[a; b],插入scipy的linprog,return成功,得到正确答案:sum(b)的最优值为0.5。但是,它 returns 的 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 文档,松弛度为 0 表示约束处于活动状态,因此第一个和第三个零表示 a1=b1=0,第二个零表示 a2=b2 并且它们不为零(否则第 4 个松弛也将为 0)。这再次符合预期,因为 [0, 0.5] 是解决方案。
我做错了什么?这是一个错误吗? (使用 scipy 0.15.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])
我尝试用 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])