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

时间:2015-08-13 23:47:35

标签: 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)

但是,这会引发错误:

---------------------------------------------------------------------------
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

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

1 个答案:

答案 0 :(得分:6)

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

from scipy.optimize import minimize
import numpy as np

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

pricesxp是向量,而不是矩阵,使用np.array([1.5,50,30])来声明向量

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

你的右侧功能不依赖于x,因此你的功能只是不变的。另外*在python中是元素方面的。您可以使用np.dot来计算标量积。

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

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

x
cons = ({'type': 'ineq', 'fun': lambda x:  -x*0.25 + 500},
        {'type': 'ineq', 'fun': lambda x:  x*0.25})

这很好,但是当向量变长时,bnds = ((0, None), (0, None), (0, None)) 会派上用场。

bnds = [(0,None)] * 3

res = minimize(fun, (2,0,0), method='SLSQP', bounds=bnds, constraints=cons) 中的函数和所有限制都是线性的。因此,这是一个线性程序,x可能不是解决它的最佳方法。对于此示例,您可能希望查看SLSQP

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

结果如下:

scipy.optimize.linprog