使用python scipy.optimize.minimize进行优化

Joh*_*nes 0 python optimization scipy

我想优化泵存储工厂的时间表.基本上有96个已知价格(当天的每个季度),模型应决定是否(1)泵,(2)涡轮机或(3)每个季度都不做任何事情.因此,X:-100有一些界限

首先,我尝试了以下内容:

from scipy.optimize import minimize
import numpy as np

prices=np.array([[1.5,50,30]])
xp =np.array([[1.5,50,30]])

fun = lambda x: xp* prices #here xp and prices should be matrices

cons = ({'type': 'ineq', 'fun': lambda x:  (xp*0.25)<=500},
    {'type': 'ineq', 'fun': lambda x: (xp*0.25)>=0})

bnds = ((0, None), (0, None), (0, None))

res = minimize(fun, (2, 0,0), method='SLSQP', bounds=bnds, constraints=cons)
Run Code Online (Sandbox Code Playgroud)

但是,这会引发错误:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-17-15c05e084977> in <module>()
     10 bnds = ((0, None), (0, None), (0, None))
     11 
---> 12 res = minimize(fun, (2, 0,0), method='SLSQP', bounds=bnds, constraints=cons)

/Users/ch/miniconda/envs/sci34/lib/python3.4/site-packages/scipy/optimize/_minimize.py in minimize(fun, x0, args, method, jac, hess, hessp, bounds, constraints, tol, callback, options)
    450     elif meth == 'slsqp':
    451         return _minimize_slsqp(fun, x0, args, jac, bounds,
--> 452                                constraints, callback=callback, **options)
    453     elif meth == 'dogleg':
    454         return _minimize_dogleg(fun, x0, args, jac, hess,

/Users/ch/miniconda/envs/sci34/lib/python3.4/site-packages/scipy/optimize/slsqp.py in _minimize_slsqp(func, x0, args, jac, bounds, constraints, maxiter, ftol, iprint, disp, eps, callback, **unknown_options)
    375 
    376             # Now combine c_eq and c_ieq into a single matrix
--> 377             c = concatenate((c_eq, c_ieq))
    378 
    379         if mode == 0 or mode == -1:  # gradient evaluation required

ValueError: all the input arrays must have same number of dimensions
Run Code Online (Sandbox Code Playgroud)

我不知道为什么会出现这个错误.有人可以给我一个暗示吗?

cel*_*cel 6

我将逐行浏览您的代码并突出显示一些问题:

from scipy.optimize import minimize
import numpy as np

prices=np.array([[1.5,50,30]])
xp =np.array([[1.5,50,30]])
Run Code Online (Sandbox Code Playgroud)

prices并且xp是向量,而不是矩阵,用于np.array([1.5,50,30])声明向量


fun = lambda x: xp* prices #here xp and prices should be matrices
Run Code Online (Sandbox Code Playgroud)

你的右侧功能不依赖x,因此你的功能只是不变的.同样*是件明智的蟒蛇.您可以使用它np.dot来计算标量积.

fun = lambda x: np.dot(x, prices)
Run Code Online (Sandbox Code Playgroud)
cons = ({'type': 'ineq', 'fun': lambda x:  (xp*0.25)<=500},
    {'type': 'ineq', 'fun': lambda x: (xp*0.25)>=0})
Run Code Online (Sandbox Code Playgroud)

这不是约束的定义方式.您可能想查看文档.不等式由集合函数表示g_i(x).凡g_i(x) >= 0所有i.同样的问题如上所述:x未在函数声明的右侧使用.

cons = ({'type': 'ineq', 'fun': lambda x:  -x*0.25 + 500},
        {'type': 'ineq', 'fun': lambda x:  x*0.25})
Run Code Online (Sandbox Code Playgroud)
bnds = ((0, None), (0, None), (0, None))
Run Code Online (Sandbox Code Playgroud)

这很好,但是bnds = [(0,None)] * 3当向量变长时会派上用场.


res = minimize(fun, (2,0,0), method='SLSQP', bounds=bnds, constraints=cons)
Run Code Online (Sandbox Code Playgroud)

功能和所有限制都是线性的x.因此,这是一个线性程序,SLSQP可能不是解决它的最佳方法.对于此示例,您可能希望查看scipy.optimize.linprog.


作为旁注:我想这只是一个玩具的例子.显然,这种优化的结果是零向量.

这是结果:

 njev: 3
       x: array([ 0.,  0.,  0.])
     nit: 3
  status: 0
 message: 'Optimization terminated successfully.'
     jac: array([  1.5,  50. ,  30. ,   0. ])
 success: True
     fun: 0.0
    nfev: 15
Run Code Online (Sandbox Code Playgroud)