Scipy使用更复杂的函数优化linprog

时间:2016-11-25 19:05:13

标签: python scipy mathematical-optimization linear-programming

我正在尝试以以下形式优化函数:

1*abs(x_0) + 1*abs(x_1) + .. + 1*abs(x_n)

函数中的系数始终为1,但x i 的值有条件,例如

x 2 - x 3 < = 7 x 3 - x 4 < = 4 等。

我正在使用scipy.optimize.linprog,但这只能解决以下形式的函数:

a_0*x_0 + a_1*x_1 + .. + a_n*x_n

有没有办法将scipy.optimize.linprog用于第一个函数?

1 个答案:

答案 0 :(得分:1)

问题:

Minimize 1*abs(x_0) + 1*abs(x_1) + ... + 1*abs(x_n))
s.t.     x_2 - x3 <= 7

可以转换成问题:

Minimize 1*y_0 + 1*y_1 + ... + 1*y_n
s.t.     x_2 - x3 <= 7
         -y_i <= x_i <= y_i  // for i in n

这里我们介绍了新变量y_0, ..., y_n

所以你的一个稍微修改过的问题(假设:最小化)看起来像这样:

from scipy.optimize import linprog
import numpy as np

N = 5
N_AUX = N

c = np.hstack((np.zeros(N), np.ones(N_AUX))) # objective -> sum of aux-vars

A_orig = [[0, 1, -1, 0, 0, 0, 0, 0, 0, 0],   # orig constraint 1
          [0, 0, 1, -1, 0, 0, 0, 0, 0, 0],   # orig constraint 2
          [-1, -1, 0, 0, 0, 0, 0, 0, 0, 0],  # more interesting problem
          [0, -1, -1, 0, 0, 0, 0, 0, 0, 0]]  # ""   ""          ""

A_aux = [[-1, 0, 0, 0, 0, -1, 0, 0, 0, 0],
         [0, -1, 0, 0, 0, 0, -1, 0, 0, 0],
         [0, 0, -1, 0, 0, 0, 0, -1, 0, 0],
         [0, 0, 0, -1, 0, 0, 0, 0, -1, 0],
         [0, 0, 0, 0, -1, 0, 0, 0, 0, -1],
         [1, 0, 0, 0, 0, -1, 0, 0, 0, 0],
         [0, 1, 0, 0, 0, 0, -1, 0, 0, 0],
         [0, 0, 1, 0, 0, 0, 0, -1, 0, 0],
         [0, 0, 0, 1, 0, 0, 0, 0, -1, 0],
         [0, 0, 0, 0, 1, 0, 0, 0, 0, -1]]

A = np.vstack((A_orig, A_aux))

b = [7, 4, -5, -8] + [0 for i in range(N_AUX*2)]
bnds = [(0, 50) for i in range(N)] + [(None, None) for i in range(N_AUX)] # some custom bounds

res = linprog(c, A_ub=A, b_ub=b, bounds=bnds)

print(res)

#     fun: 8.0
# message: 'Optimization terminated successfully.'
#     nit: 10
#   slack: array([  5.,   1.,   0.,  10.,   6.,   0.,   0.,   0.,   0.,          0.,   0.,
#     0.,  50.,  45.,  47.,  50.,  50.,   0.,   0.])
#  status: 0
# success: True
#       x: array([ 0.,  5.,  3.,  0.,  0.,  0.,  5.,  3.,  0.,  0.])

如果您对安装库有一点了解,我建议使用cvxpy

  • 自动进行此类转换(等等)
  • 为更好的解决方案提供支持(开源和商业;基于单纯和非单纯的)

相同的例子:

from cvxpy import *

x = Variable(5)
constraints = [x[1] - x[2] <= 7,
               x[2] - x[3] <= 4,
               x[0] + x[1] >= 5,
               x[1] + x[2] >= 8,
               x >= 0,
               x <= 50]
objective = Minimize(sum_entries(abs(x)))
problem = Problem(objective, constraints)
problem.solve()
print(x.value)
print(problem.value)

# [[ -1.56436431e-11]
#  [  5.83767132e+00]
#  [  2.16232868e+00]
#  [  6.53497343e-10]
#  [  7.79511984e-10]]
# 8.00000000102