最近做的论文里面涉及到了数学规划,因此小小研究了一下,怎么用Python来实现一个数学规划,求函数最小值。这期博客主要会讲以下内容:
数学规划是什么
简单说:数学规划就是给定一些条件,求出使得目标函数最小(或最大)的参数。对于计算机不发达的年代,这种工作都是人做的,因而有好多好多不同的数学大佬,发明了许多不同的找最小值的方法。
然而,想写一个Python代码来求解数学规划问题,其实并不需要知道数学规划问题是什么,因为数学规划的算法已经以函数的形式打包好了,只需要调函数,就可以轻松求解数学规划问题。
不过你要是真的很想知道数学规划是什么,请看链接:
- https://baike.baidu.com/item/数学规划
- https://zhuanlan.zhihu.com/p/25064890
Python代码如何优雅的书写
前面已经提到,求最小值的过程可以在Python中轻松实现,Python的Scipy库实现了许多不同找最小值的方法。
参考: 官方文档.
举一个简单的例子:
res = minimize(minfunc,z,method='nelder-mead',options={'xtol' : 1e-8, 'disp' : True})
就可以完成一个找到最优解的过程,其中minfunc
是目标函数,z
是最后寻找的参数,method
是所使用的方法,在这里使用的方法是nelder-mead
值得注意的是
- 这里的
z
一定千万要是一个一维向量,不可以是二维向量 - 虽然函数很好用,但是有时会报错超界,这时候可以对数据进行归一化,减小规模再进行计算
代码背后是什么原理
官方文档中给了一些参考资料来介绍nelder-mead
方法,可以参考,比较易懂的资源是这两篇博客:
粗糙地来看,nelder-mead
对于一个n维函数的最优化问题中会有n+1个候选者,不断地更新这n+1个候选者,最终得到最优解。每次迭代都会更新1次候选者,更新的方法有4种,分别是:
- reflection
- expansion
- contraction
- shrink
nelder-mead
算法通过判断各种情况,来选择执行这4种操作的哪一种,具体细节可以看 Nelder–Mead算法详解这篇博客讲的比较清楚了,在这里不多说。