文档url:https://docs.scipy.org/doc/scipy-0.18.1/reference/generated/scipy.optimize.minimize.html

本文还是对scipy官方文档的翻译及解释(毕竟文档写的那么好),使用的函数为scipy.optimize.minimize。

函数原型为:scipy.optimize.minimize(funx0args=()method=Nonejac=Nonehess=Nonehessp=Nonebounds=Noneconstraints=()tol=Nonecallback=Noneoptions=None)

下面我就简单地介绍几个重要参数

fun:不用想了,就是优化的目标函数;

x0:非线性优化问题的求解并不是用解析的方法进行的,而是从初始值开始进行迭代,x0就是猜测的初始值,在很大程度上决定了算法的效果。另外要注意,如果是多元函数,那么就要将x0视为一个向量,每一个分量都要单独赋值;

args:可选项,如果目标函数有可设定的参数,可以用这种方式传递进去;

method:选用的优化算法,有12种可选项,比较常用的为SLSQP(Sequential Least Squares Programming),算法种类很多,这里也不详细说了(其实是我自己也不怎么清楚,乱讲怕坑人);

但是看发表时间,2017年就没再更新过,应该是早就鸽了......不过写的部分内容还是挺不错的。

bounds:用法和linprog里面的完全一样,可以参考我的上一篇博客;

constraints:优化的约束条件,输入为字典组成的元组,字典主要由'type'和'fun'组成,type可选'eq'和'ineq',分别是等式约束和不等式约束,fun理所当然就是对应的约束条件,可以为lambda函数。例如,约束x0大于min的字典可以这样写:{'type': 'ineq', 'fun': lambda x: x[0] - min}(x为输入的数组,x[0]为第一个元素)可选的还有jac和args,在此就不展开说了。

tol:设定默认的误差阈值,低于阈值就会停止迭代,一般而言设定的越小越精确,很多优化算法都会有这一设定项。

官方文档里给出了一些示例,比如无约束优化:

>>> from scipy.optimize import minimize, rosen, rosen_der
>>> x0 = [1.3, 0.7, 0.8, 1.9, 1.2]
>>> res = minimize(rosen, x0, method='Nelder-Mead', tol=1e-6)
>>> res.x
array([ 1.,  1.,  1.,  1.,  1.])

这个例子里用到了resen函数,也就是Rosenbrock函数,经常被用来测试最优化算法的性能,当自变量为二维时,在三维空间里绘出函数图像为:

Python非线性分类代码 python非线性规划_数学建模

(图片来自wikipedia)

不过这不是本文要讨论的重点,总而言之此处的参数rosen就是一个函数,和自己def的没有本质区别,使用方法也是一样的。

然后输出结果就是优化得出的解。

 

有约束的规划文档中也给出了例子:

>>> from scipy.optimize import minimize
>>> fun = lambda x: (x[0] - 1)**2 + (x[1] - 2.5)**2
>>> cons = ({'type': 'ineq', 'fun': lambda x:  x[0] - 2 * x[1] + 2},
...         {'type': 'ineq', 'fun': lambda x: -x[0] - 2 * x[1] + 6},
...         {'type': 'ineq', 'fun': lambda x: -x[0] + 2 * x[1] + 2})
>>> bnds = ((0, None), (0, None))
>>> res = minimize(fun, (2, 0), method='SLSQP', bounds=bnds,
...                constraints=cons)

该优化问题的理论解为(1.4, 1.7)。

以上就是minimize函数的基本用法。