解最优化问题
来源:互联网 发布:app p图软件 编辑:程序博客网 时间:2024/06/09 08:46
解最优化问题
本文版权属于重庆大学计算机学院刘骥,禁止转载
- 解最优化问题
- 最优化问题的分类
- 直接开始求解
- downhill simplex
- Conjugate Gradient
- 你居然不会求偏导数
- Newton-CG
- 总结
- 数学原理
- 数学白痴的福利
最优化问题的分类
按照目标函数的可导性,可以将最优化问题分为两类:
1. 目标函数可导,例如目标函数为
2. 目标函数不可导,例如目标函数为
对于不可导的目标函数,其解法比较特殊。采用模拟退火算法、粒子群算法、遗传算法、蚁群算法、图割(Graph Cut)算法等方法,可以求解这类问题,但通常无法得到精确的解(或者说全局最优解)。并且有些问题,仅能用特定的解法,求出特定的解。由于该类问题的复杂性,本文对不可导目标函数问题不进行讨论。如果你在实际中遇到了这类问题,可以采用如下方法解决:
查学术论文,github上找代码;如果找不到解决方案,恭喜你,这是一个获得数学大奖的机会
本文余下部分,针对可导的目标函数进行讨论,这类问题存在大量通用的算法。人类历史发展到2017年,你甚至不需要了解具体算法的原理,也能够很happy的解决这类问题。
直接开始求解
下面我们用一个简单的最优化问题为例:
显然
downhill simplex
Python语言的scipy.optimize包的fmin函数实现了downhill simplex方法,也称为Nelder–Mead方法(downhill、simplex和downhill simplex是不同的概念,有兴趣可以参考维基百科)。这里不去讲解downhill simplex的原理,有需要原理的读者,请移步到https://en.wikipedia.org/wiki/Nelder–Mead_method。
fmin函数的说明如下:
我估计你看不懂,所以我不准备解释。我们直接看代码吧。
# encoding=utf-8import scipy.optimize as opt#定义目标函数fdef f(X): x=X[0] y=X[1] return x**2+y**2+1;x=10y=10X=[x,y]X=opt.fmin(f,X) #f是目标函数,X是初始猜测的解x=X[0]y=X[1]print x,y
程序执行结果如下:
最终
Conjugate Gradient
downhill simplex比较简单,实现没有难度。但它的问题在于比较慢,下面我们试试 Conjugate Gradient法。使用scipy.optimize包的fmin_cg方法。这个方法需要求出目标函数的偏导数(梯度):
# encoding=utf-8import scipy.optimize as optimport numpy as np#定义目标函数fdef f(X): x=X[0] y=X[1] return x**2+y**2+1;#定义目标函数f对应的梯度函数def gradf(X): x=X[0] y=X[1] gx=2*x gy=2*y return np.asarray((gx,gy)) #梯度以向量形式返回x=10y=10X=[x,y]X=opt.fmin_cg(f,X,fprime=gradf) #f是目标函数,X是初始猜测的解,增加梯度x=X[0]y=X[1]print x,y
运行结果如下:
可以看出该方法比downhill simplex运行得更快。当然这是显然的,因为有了梯度信息。
你居然不会求偏导数!
OK!OK!有办法可以解决!今年是2017年,如果你还不会求偏导数,那么交给计算机吧!
X=opt.fmin_cg(f,X)
OK!计算结果如下:
慢了一些,函数的演化次数增加了15次,why?因为算法用数值法来计算梯度!具体来说(你可以忽略下面的内容,把问题交给人工智能):
def gradf(X): x=X[0] y=X[1] gx=(f([x+0.0000001,y])-f([x,y]))/0.0000001 gy=(f([x,y+0.0000001])-f([x,y]))/0.0000001 return np.asarray((gx,gy))
也就是:
Newton-CG
试试Newton-CG,也就是fmin_ncg函数,该函数需要2阶偏导数构成的Hessian矩阵:
代码如下:
# encoding=utf-8import scipy.optimize as optimport numpy as np#定义目标函数fdef f(X): x=X[0] y=X[1] return x**2+y**2+1;#定义目标函数f对应的梯度函数def gradf(X): x=X[0] y=X[1] gx=2*x gy=2*y return np.asarray((gx,gy)) #梯度以向量形式返回def hess(X): return np.array([[2,0],[0,2]]) #hessian矩阵x=10y=10X=[x,y]X=opt.fmin_ncg(f,X,fprime=gradf,fhess=hess) #f是目标函数,X是初始猜测的解,增加梯度x=X[0]y=X[1]print x,y
运行结果如下:
非常精确!当然如果不会计算hessian,如下操作:
X=opt.fmin_ncg(f,X,fprime=gradf) #注意梯度是必须的
结果如下:
总结
现在是2017年,基本的最优化问题已经经过了几百年的发展(不是几十年),因此有大量现成的函数库可以使用。直接调用这些库函数,你甚至不需要知道如何求导数、如何求Hessian矩阵,也可以很好的解决最优化问题(可导的)。如果不追求效率,如果精度可以接受,那么最最原始的downhill simplex方法已经能够适用于大多数场景(你需要小数点后几位的精度?)。
数学原理
大多数最优化的书籍,在讲解数学原理时,都抱着一定要让人看不懂,才能显得高深莫测的心态。其实求解可导目标函数的数学原理是极其简单的,那就是:穷举,更高效的穷举。
假设目标函数为
学过代数吧?于是这个函数就变成了:
现在我们来讨论女性择偶函数f(X)的最优化!假定女性朋友给出的函数是这样的:
这是一个二次函数(请自行展开),C是系数矩阵(我们只是假设女性朋友给出了这样的二次函数,真实情况未必)。OK,其实这个函数长什么样子,不影响后面的讨论。我们所要讨论的是
最笨的方法就是穷举!!换言之,先试试
聪明一点的方式是穷举n次,找其中的最优。先试试
再聪明一点的方法固定一些变量,搜索另外一些变量。必须长得帅,像鹿晗;必须有钱,和王思聪一样;必须是初恋。你看解空间一下就变小了。接下来的搜索就简单了很多。如果找不到解,那么就修改某些固定的变量。为什么长相必须像鹿晗?郭德纲也可以接受!这样我们就可以开始新的搜索啦!事实上,这就是绝大多数人,择偶的方式。
如果变量是连续的呢?数学家发现,在这种情况下,搜索策略其实是这样的:
1. 首先选择一个起始的解
2. 比较
3. 另
上述方法的核心在于存在一个
上述算法有三个终止条件:
1. 迭代次数达到限额(都已经120岁的单身贵族啦!)
2.
3.
下面举个例子,目标函数如下:
假设初始值为
Stop!不是
怎么解决这个问题呢?数学家出场了。我们知道
针对该公式求
现在我们可以解出
计算过程如下:
数学白痴表示求偏导数矩阵太难理解!!如何破!!数学家马上送上福利:
假设
运气不错!如果
如果
可见如果采用新的计算公式,
最后,再来考虑一下,如果数学白痴连梯度都不会算怎么办?Nelder–Mead Method!对有高等数学背景的人而言,理解Nelder–Mead Method反而很困难!这里就不再详谈了。
数学白痴的福利
我们都不喜欢数学,还好现在是2017年,大量的工作已经由擅长数学的科学家做完了。你所需要的就是找一个算法丰富的库!比如Python的scipy或者matlab。为了写作本文,我对最优化问题进行了很多简化,首先只考虑可导的目标函数,其次也没有考虑函数变量的条件约束(比如
- 解最优化问题
- 无约束最优化问题
- 无约束最优化问题
- 最优化问题简介
- 最优化问题简介
- 最优化问题综述
- 最优化问题综述
- 最优化问题综述
- 最优化问题
- 最优化问题
- 最优化问题及其分类
- SVM的最优化问题
- MATLAB 求解最优化问题
- 最优化问题-线性优化(LP)
- 任务处理——最优化问题
- 机器学习中的最优化问题
- 机器学习中的最优化问题
- 无约束问题的最优化方法
- P2P原理简介
- CDH5.12.1版本搭建记录
- ros之真实驱动diy6自由度机械臂
- cookie&session(two)
- 运动目标检测算法相关概念
- 解最优化问题
- mybatis TypeHandler处理自定义枚举类型
- activeMQ简单事例应用
- [翻译]设备树的用法(Device Tree Usage)
- 设置cookie的方法
- Java 面试题笔记
- cookie和session
- java并发编程-基础原理
- 计算机网络原理(二)