简体   繁体   English

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

[英]Optimize with python scipy.optimize.minimize

I would like to optimize the schedule of a pump storage plant. 我想优化泵存储工厂的时间表。 Basically there are 96 known prices (for each quarter of the day) and the model should decide whether to (1) pump, (2) turbine or (3) do nothing for each respective quarter. 基本上有96个已知价格(一天中的每个季度),该模型应确定是(1)泵,(2)涡轮还是(3)每个季度都不进行任何操作。 Thereby, there are some bounds for X: -100 因此,X有一些界限:-100

To start I tried the following: 首先,我尝试了以下操作:

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)

However, this throws an error: 但是,这将引发错误:

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

I have no clue why this error appears. 我不知道为什么会出现此错误。 Can somebody give me a hint? 有人可以给我提示吗?

I'll go through your code line by line and highlight some of the problems: 我将逐行介绍您的代码,并重点介绍一些问题:

from scipy.optimize import minimize
import numpy as np

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

prices and xp are vectors, not matrices, use np.array([1.5,50,30]) to declare vectors pricesxp是向量,而不是矩阵,请使用np.array([1.5,50,30])声明向量


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

Your right side of the function does not depend on x , therefore your function is simply constant. 您函数的右侧不依赖x ,因此您的函数只是常量。 Also * is element-wise in python. 另外*在python中是元素明智的。 You can use np.dot to calculate the scalar product. 您可以使用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})

This is not how constraints are defined. 这不是定义约束的方式。 You may want to check the docs. 您可能要检查文档。 Inequalities are expressed by a set functions g_i(x) . 不等式由集合函数g_i(x) Where g_i(x) >= 0 for all i . 其中所有i g_i(x) >= 0 Also same problem as above: x is not used in the right side of your function declaration. 与上面同样的问题:函数声明的右侧未使用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))

This is fine, however bnds = [(0,None)] * 3 will come in handy when the vectors grow longer. 这很好,但是当向bnds = [(0,None)] * 3bnds = [(0,None)] * 3上用场。


res = minimize(fun, (2,0,0), method='SLSQP', bounds=bnds, constraints=cons)

Both the function and all restrictions are linear in x . 函数和所有限制在x都是线性的。 Thus this is a linear program, and SLSQP may not be the best way to tackle it. 因此,这是一个线性程序, SLSQP可能不是解决它的最佳方法。 For this example, you may instead want to have a look at scipy.optimize.linprog . 对于此示例,您可能想要查看scipy.optimize.linprog


As a side note: I guess this is only a toy example. 附带说明:我想这只是一个玩具示例。 Obviously the result of this optimization is the zero vector. 显然,此优化的结果是零向量。

This is the result: 结果如下:

 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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM