本帖最后由 2支棒棒糖 于 2018-8-17 14:21 编辑
在MATLAB中求解优化问题需要遵循一定的程序,这些程序包括选择求解器、设置变量、写目标函数、写约束条件、设置求解器参数、求解并检查结果和改善优化结果;虽然不是在每个问题的求解过程中都需要这几个步骤。 1、选择求解器 选择求解器前,需要确定目标方程的类型,可从以下5个选项中选择确认:线性(Linear);二次(Quadratic);最小二乘(Least Squares);平滑非线性(Smooth nonlinear);非平滑(Nonsmooth)。 然后,确定约束方程属于下面哪一类:无约束(None);边界(Bound);线性(Linear);平滑(General smooth);离散值(Discrete),最后选择求解器。 2、设置变量 设置变量包括:确定优化的目标和约束;根据目标和约束确定所有变量;将变量写入向量中。 3、写目标函数 目标函数包括:单变量目标函数;向量和矩阵目标函数组;线性规划或二次规划目标函数。 这些目标函数的写入方式如下文所示。 ①写单变量目标函数 单变量目标函数允许输入一个参数,该参数可以为标量、向量或矩阵;该函数所在的函数文件(如使用)可输出超过一个结果。 例11-1,写下面目标函数的函数文件,并检验: f (x ) = (x − y )三次方− x /(1 + x平方+ z平方 ) + cosh(x −1) 打开M文件编辑器,并写入: - <p style="line-height: 30px; text-indent: 2em;"><span style="text-indent: 2em;">function f = myObjective11_1(xin)</span></p><p style="line-height: 30px; text-indent: 2em;">f = (xin(1)-xin(2))^3 + xin(1) /(1+ xin(1)^2+ xin(3)^2)+ cosh(xin(1)-1) ;</p>
复制代码保存文件为myObjective11_1.m到当前路径。 在命令行窗口输入: 输出结果如下: 提示:通过输出更多的参数,还可以在函数文件输出结果中输出导数。例如可以编写程序,使输出结果依次为目标函数、梯度和偏导。 例11-2,从目标函数文件中输出导数。该函数如下: f (x ) = 100(x2 - x1平方)平方 - (1 - x1 )平方 打开M文件编辑器,并写入: - function [f g H] = myObjective11_2(x) % 计算目标函数
- f = 100*(x(2) - x(1)^2)^2 + (1-x(1))^2;
- if nargout > 1 %计算导数
- g = [-400*(x(2)-x(1)^2)*x(1)-2*(1-x(1)); 200*(x(2)-x(1)^2)];
- if nargout > 2 %计算偏导
- H = [1200*x(1)^2-400*x(2)+2, -400*x(1); -400*x(1), 200];
- end
- end
复制代码保存文件为myObjective11_2.m到当前路径。 在命令行窗口输入: - [f g H]=myObjective11_2([1;2;3])
复制代码输出结果如下: - f = 100
- g = -400
- 200
- H =402 -400
- -400 200
复制代码②写向量和矩阵目标函数组 向量和矩阵目标函数组与单个目标函数相似,但要注意输出的目标函数和导数等均有些不同。 例11-3,写向量和矩阵目标函数组示例。待写入的函数组为: 打开M文件编辑器,并写入: - function [F jacF] = myObjective11_3(x)
复制代码保存文件为myObjective11_3.m到当前路径。 在命令行窗口输入: - [F jacF]=myObjective11_3([1;2;3])
复制代码输出结果如下: - F = 7.0000
- 0.7568
- jacF = 2.0000 3.0000 2.0000
- -0.6536 -1.3073 1.9609
复制代码③写线性规划或二次规划目标函数 线性规划的目标函数为: - f'x = f(1)*x(1) + f(2)*x(2)+...+ f(n)*x(n)
复制代码二次规划的目标函数为: 1/2*x'Hx+f'x=1/2*(x(1)*H(1,1)*x(1)+2*x(1)*H(1,2)*x(2)+...+x(n)*H(n,n)*x(n))+f(1)*x(1)+...+f(n)*x(n). 其中,f'为f的倒置向量,H为f的偏导数。 写线性规划或二次规划目标函数一般不需要写函数文件,只需要将相应的数据按照格式准备好,在求解的时候代入相应的函数即可。 4、写约束条件 MATLAB提供的约束条件包括以下四种类型: 边界约束——为参数的上下边界(例如:x ≥ l且x ≤ u)。 线性不等式约束——A·x ≤ b。 线性等式约束——Aeq·x = beq。 非线性不等式/等式约束——c(x) ≤ 0或ceq(x) = 0。 提示:为提高效率,可将一些其他类型的约束转化为边界约束。 5、设置求解器参数 MATLAB提供了optimset函数用于设置求解器参数,该函数的调用格式如下所示: - options = optimset('param1',value1,'param2',value2,...)
- optimset
- options = optimset
- options = optimset(optimfun)
- options = optimset(oldopts,'param1',value1,...)
- options = optimset(oldopts,newopts)
复制代码其中, options = optimset('param1',value1,'param2',value2,...)创建options的优化选项参数,使用特定参数'paramN'、valueN进行设置。未设置的参数都设置为空矩阵[]。 optimset函数没有输入输出变量时显示完整的带有有效值的参数列表。 options = optimset(optimfun)创建含有所有参数名和与优化函数optimfun相关的缺省值的选项结构options。 options = optimset(oldopts,'param1',value1,...)创建oldopts的拷贝,并用指定的数值修改参数。 options = optimset(oldopts,newopts)将oldopts与新的选项结构newopts进行合并。newopts参数中元素将覆盖oldopts参数中对应元素。 例11-4,使用optimset设置参数。 在命令行窗口输入: - display('显示完整的带有有效值的参数列表:')
- optimset
- display('设置Display为iter:')
- options1 = optimset('Display','iter')
- display('修改options1的TolFun项为1e-10:')
- options2 = optimset(options1,'TolFun', 1e-10)
复制代码输出结果如下:
- 显示完整的带有有效值的参数列表:
- Display:[off | iter |iter-detailed |notify | notify-detailed | final |
- final-detailed ]
- MaxFunEvals: [ positive scalar ]
- MaxIter: [ positive scalar ]
- TolFun: [ positive scalar ]
- %%%%省略部分%%%
- 设置Display为ite0072:
- options1 =
- Display: 'iter'
- MaxFunEvals: []
- MaxIter: []
- TolFun: []
- %%%%省略部分%%%
- 修改options1的TolFun项为1e-10:
- options2 =
- Display: 'iter'
- MaxFunEvals: []
- MaxIter: []
- TolFun: 1.0000e-10
- %%%%省略部分%%%
复制代码6、求解并检查结果 需要检查的结果包括求解器输出和迭代过程: 对于求解器输出,需要检查输出参数的结构和正确性; 对于迭代过程,可以在需要的时候通过设置optimset函数的'Display'选项为'iter'来进行显示。 注意:这在结果出错或不收敛的时候非常有用。 7、改善优化结果 改善求解结果一般包括以下4个基本方面:使结果可靠;如果求解失败,则改善求解方案,再次求解;确定求得的最小值是值域范围内最小值还是小区域范围内的最小值;对于时间开销过大的求解,应改善求解条件,降低时间开销。
|